Write a Steemit Web App: Part 12 - Voting

(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)

H2
H3
H4
3 columns
2 columns
1 column
10 Comments