Write a Steemit Web App: Part 12 - VotingsteemCreated with Sketch.

in #steemdev7 years ago (edited)

(Previous Post: Part 11)

Over the past few posts, we've taken a look at how to fetch content. But, how can your web app support the authors of that content by upvoting?

Voting

Let's face it: People post content to Steemit because they want to be paid. That's what is unique about our platform when compared to other social media, such as Reddit or even Medium. Content is rewarded by means of being upvoted by other users. The more Steem Power that a voter has, the bigger the reward that the content will receive from that vote.

Casting a vote is really not very different than other broadcast api calls that were made in this series:

steem.broadcast.vote(wif, voter, author, permlink, weight)


wif refers to the private posting key for the specified voter (i.e., the account casting the vote). author and permlink refer to the content itself.

Finally, weight is the percentage of a vote that is being applied, multiplied by 100. So, for 100%, weight would be 10000. For 10.25%, use a value of 1025, etc.

Note: If the vote's rshares (see below) is under a certain threshold, then it is considered to be Dust and will be rejected. This is a contributing factor to why accounts with less than 500 SP do not have the Voting Percent slider on Steemit.com.

How much is an upvote worth?

Disclaimer: I have worked out much of this logic by reading the Steem source code. It may not be completely correct, and I welcome commentary so that I can update the post with correct behavior for the benefit of everyone using this as a reference.

To understand how much a vote is worth, let's first consider how money is magically created by Steem.

New Steem is created every time a block is added to the blockchain (think: block reward). This is due to pure inflation, so it dilutes the Steem Power that all accounts hold over time. Unlike a tax, individual account balances don't decrease, but the percentage of the total pool of Steem that an account controls is reduced with each block.

Note: This is why even Whales need to keep creating content in order to prevent their Steem Power from eroding over time.

The amount of new Steem created by a block can be calculated as:

const STEEMIT_INFLATION_RATE_START_PERCENT = 9.78 // will decay to start at 9.5% for block 7000000
const STEEMIT_INFLATION_RATE_STOP_PERCENT = 0.95  // will not go below 0.95%
const STEEMIT_INFLATION_NARROWING_PERIOD = 250000 // decreases by 0.01% every 250k blocks
const STEEMIT_BLOCK_INTERVAL = 3 // New block every 3 seconds
const STEEMIT_BLOCKS_PER_YEAR = (365*24*60*60/STEEMIT_BLOCK_INTERVAL) // 20 blocks per minute over 365 days

const current_inflation_rate = Math.max(
  (STEEMIT_INFLATION_RATE_START_PERCENT - (Current_Block_Num / STEEMIT_INFLATION_NARROWING_PERIOD)),  
  STEEMIT_INFLATION_RATE_STOP_PERCENT
)

let new_steem = (gprops.virtual_supply * current_inflation_rate) / (STEEMIT_BLOCKS_PER_YEAR)


Inflation is described in the source code as:

At block 7,000,000 have a 9.5% instantaneous inflation rate, decreasing to 0.95% at a rate of 0.01% every 250k blocks. This narrowing will take approximately 20.5 years and will complete on block 220,750,000

75% of the new Steem goes into a reward fund that is used to pay out rewards at the end of the week of voting for new content. You can retrieve information about the reward fund using the getRewardFund() function:

steem.api.getRewardFundAsync("post")
  .then(console.log)
  .catch(console.error)


Results:

{
  author_reward_curve:"linear",
  content_constant:"2000000000000",
  curation_reward_curve:"square_root",
  id:0,
  last_update:"2017-08-13T01:44:18",
  name:"post",
  percent_content_rewards:10000,
  percent_curation_rewards:2500,
  recent_claims:"230241280990236001",
  reward_balance:"702826.275 STEEM"
}


Let's look at what is recorded for a vote:

steem.api.getContentAsync('jfollas', 'write-a-steemit-web-app-part-11-posting-content')
  .then(console.log) 


Results:

{
    ...
    active_votes: [
        {
          voter: "transisto",
          weight: 2938546,
          rshares: "8731552687551",
          percent: 10000,
          reputation: "24586070159815",
          time: "2017-08-08T04:23:33"
        },
        ...
    ],
    ...
}


Here, @transisto gave a 100% upvote (thanks!). How much was that vote worth? Well, take the rshares from the vote and divide by the recent_claims from the fund to get a percentage of the fund that this vote represents, and then multiply by the reward_balance in the fund:

const pot = parseFloat(fund.reward_balance.replace(' STEEM', ''))
const total_r2 = parseInt(fund.recent_claims, 10)

let contrib = v.rshares * pot / total_r2
console.log(`${v.voter}: ${contrib} STEEM\n`)

// Result: 
// transisto: 26.65362451061 STEEM


To convert to SBD, you need to have the conversion factor from the current feed:

steem.api.getFeedHistoryAsync()
  .then(console.log)


Results:

{
  id: 0,
  current_median_history: {
    base: "1.236 SBD",
    quote: "1.000 STEEM"
  },
  price_history: [
  {
    base: "1.317 SBD",
    quote: "1.000 STEEM"
  },
  {
    base: "1.296 SBD",
    quote: "1.000 STEEM"
  },
  ...
 }


According to current_median_history, 1 STEEM = 1.236 SBD, so transisto's vote should have been worth 32.944 SBD. The calculated SBD payout will fluctuate with the market value until the content is actually paid out at the end of the 7-day voting period (and then the conversion rate will be locked in at that point in time).

javascriptlogo.png

(Next Post: Part 13)

Sort:  

Anyone know how to get accurate historic payout values? Doesn't the figure used here for the reward pool balance relate to the present moment rather than to a specific time?

I'm looking for this now. :) I assume you solved your doubt at a certain point in time. Can you share your solution?

The only solution I have found for this involves looping through the array of votes that is stored, iirc, against comments - but i would need to look through my code and I am about to go to bed here ;)
If you are able to look at the database of the blockchain, you should be able to find an array that contains vote data and can figure it out from there. I'll look tomorrow if you still need more help.

All I can find is RShares and a time. I'll keep looking. Thanks! All I could think of was accessing historical reward pool data and comparing to that, but it would be less efficient if there were some other way.

Once again you're right ahead of me. I've been trying to figure out the worth of single upvotes, but you've already solved it for me. Thanks :D

Excellent work! Thank you for it.

Just a clarification: The Steem Power is not diluted, but only the Steem. Because the Steem Power is the price of VESTS. And although the VESTS increase also the users does power down and therefore their amount is kept stable.
I have analysed some data here about this.

Is there anyway to get the current price of SBD & Steem from SteemJS?

Is there any way we can get this put in as part of the official API docs? Seriously, I've been searching forever to find out how to calculate the value of an upvotes!! Thanks for finally giving me a solid answer... if only I'd found this earlier and not wasted 10 hours of Google searches...