Posts

[개발] 스팀 예상 보상금액 조회

avatar of @wonsama
25
@wonsama
·
0 views
·
2 min read

[그림] 특정 계정의 현재 스팀파워와 보팅마나 및 100%로 보팅 시 예상 금액

보팅금액 환산

기본적으로 보팅금액은 포스팅 리워딩풀에 쌓인 금액을 스팀 파워에(리워드 쉐어 합계) 비례하여 나눠 갖는다고 생각하심 됩니다.

관련 소스코드

기본적으로 steemdnow.com 사이트 정보를 기반으로 작업해서 만들었네요 :)

해당 예상금액은 보팅하는 순간의 예상 금액이며, 리워드 풀에 참여자가 많아지면 물론 보상 수령 금액은 줄어들게 됩니다. ( 빵 하나를 한명이 아닌 두명 세명이 나눠 먹으면 그 양이 줄어드는 것과 유사하죠, 거기에 힘이 센(보팅파워) 사람이 더 많이 먹는 것이고여 )

// 해당 계정의 보팅 파워를 계산해 준다 
const get_vp = (authors)=>{ 
 
  const __MAX_VOTING_POWER = 10000; 
  const __CHARGE_PER_SEC = 60 <em> 60 </em> 24 <em> 5;  // 432000, 1초당 충전되는 수치, </em>5는 하루 20% 1/5을 의미함 
 
  const __parse = (r) => { 
 
    let account = r.name; 
    let last = r.voting_power; //최근 투표일 기준 보팅파워 , 10000 is max 
    let gap = (new Date().getTime() - new Date(r.last_vote_time + "Z").getTime())/1000; // 최종 보팅한 이후 흐른 시간, 초 
    let vp = Math.min(__MAX_VOTING_POWER, parseInt(last +  ( gap / __CHARGE_PER_SEC ) * __MAX_VOTING_POWER)); // 시간차를 적용한 현재 보팅파워 10000 is max 
 
    return { 
      account, last, gap, vp,  
      vesting_shares:parseFloat(r.vesting_shares.split(' ')[0]),  // 내꺼  
      received_vesting_shares:parseFloat(r.received_vesting_shares.split(' ')[0]),  // 임대 받은거  
      delegated_vesting_shares:parseFloat(r.delegated_vesting_shares.split(' ')[0]),  // 임대 해준거 
    }; 
  } 
 
  if(authors && !Array.isArray(authors)){ 
    authors = [authors]; 
  } 
  const is_one = authors.length==1?true:false; 
 
  return send_rpc('condenser_api.get_accounts',[authors],URL_STEEM) 
    .then(res=>{ 
      if(is_one){ 
        return Promise.resolve(res.result.map(r=>__parse(r))[0]); 
      }else{ 
        return Promise.resolve(res.result.map(r=>__parse(r)));   
      } 
  }); 
} 
 
// 해당 계정의 보팅 파워와 예상 금액을 조회 
const get_vp_with_price = (author) =>{ 
  return Promise.all([ 
    get_vp(author), 
    steem.api.getRewardFundAsync('post'), 
    steem.api.getCurrentMedianHistoryPriceAsync(), 
    steem.api.getDynamicGlobalPropertiesAsync(), 
  ]).then(res=>{ 
    let _vp = res[0];  // vp.vp 
    let rf = res[1];  // rf.reward_balance, rf.recent_claims 
    let cmhp = res[2]; 
    let dgp = res[3]; 
 
    let reward_balance = parseFloat(rf.reward_balance.split(' ')[0]); 
    let recent_claims = parseInt(rf.recent_claims); 
    let base = parseFloat(cmhp.base.split(' ')[0]);   // SBD 
    let quote = parseFloat(cmhp.quote.split(' ')[0]); // STEEM 
    let total_vesting_fund_steem = parseFloat(dgp.total_vesting_fund_steem.split(' ')[0]); 
    let total_vesting_shares = parseFloat(dgp.total_vesting_shares.split(' ')[0]); 
 
    let m = total_vesting_fund_steem / total_vesting_shares; 
    let p = reward_balance / recent_claims; 
    let l = base / quote; // steem price 
    let e = parseInt(steem.formatter.vestToSteem( 
      _vp.vesting_shares+_vp.received_vesting_shares-_vp.delegated_vesting_shares,  
      total_vesting_shares, total_vesting_fund_steem)); // steempower 
    let t = _vp.vp / 100; // votingpower 
    let a = 100; // voteweight 
    let n = e / m; 
    let r = parseInt(100 * t <em> (100 </em> a) / 1e4); 
    r = parseInt((r + 49) / 50); 
    let i = parseInt(n <em> r </em> 100); 
    let o = ((i + 2e12) <em> (i + 2e12) - 4e24) / (i + 8e12) </em> p * l; 
 
    return Promise.resolve({ 
      sp:e, 
      vp:t, 
      steem_price_sbd:parseFloat(l.toFixed(2)), 
      exp_dollar:parseFloat(o.toFixed(4)), 
    }); 
  }) 
} 

맺음말

누군가에게 도움이 되길 바라면서 ...