Write a Steemit Web App: Part 3 - Current Voting Power

(Previous Post: Part 2)

What is Voting Power?

Voting Power is a rate-limiting feature of Steem to help prevent abuse. Each vote cast reduces the user's voting power by 2% of their remaining pool. So, if someone (or a bot) goes wild and upvotes hundreds of posts, then each upvote is worth less than the previous one (eventually being worth nothing).

Voting power regenerates linearly over 5 days, or 20% per day. So, with HF19, most people have set a goal of only depleting 20% of their voting power per day so that it will regenerate to 100% within 24 hours. This means that they can vote 11 times (at 100% per vote - only worth noting for those with enough steem power to unlock the ability to choose how much each vote is worth):

#Voting Power
(Start)100.00%
Vote 198.0%
Vote 296.04%
Vote 394.12%
Vote 492.24%
Vote 590.40%
Vote 688.58%
Vote 786.81%
Vote 885.08%
Vote 983.37%
Vote 1081.71%
Vote 1180.07%

Representing Voting Power in a Web App

When you fetch account information with Steem.js, such as with the getAccounts() function, you get a voting_power number in the account data object: { ..., voting_power: 9668, ... }. However, if you keep refreshing, you will not see this number ever change on its own - even if it's been five days since the last vote. This value is only updated when a user casts a vote.

Note: A LOT of the Steem applications out there are guilty of just showing this value... so even if you are really at 100% voting power, the apps won't reflect that.

But, there is another value in the account data object that is also updated when a vote is cast: {..., last_vote_time: "2017-07-03T01:12:15", ...}. So, your web app must do the task of calculating the current voting power value given these two inputs.

The basic formula is to take the reported voting_power and add in how much should have been regenerated since the last_vote_time. The maximum result would be 100%.

JavaScript Code

In the first post of this series, we used the following code in the naive way to represent the user's voting power:

vm.$set(vm.userData, 'power', result[0].voting_power / 100)


To correct this, we must first figure out how many seconds have passed:

let secondsago = (new Date - new Date(result[0].last_vote_time + "Z")) / 1000


Next, divide the secondsago by the number of seconds in 5 days (432000) in order to get a percentage of how much of the 5 days has elapsed. Multiply this by 10000 (100%) to calculate how much voting power has regenerated so far, and add to the voting_power value from the account object:

let vpow = result[0].voting_power + (10000 * secondsago / 432000)


Now we can set the value in our viewmodel (taking care of formatting and ensuring that the max is 100%):

vm.$set(vm.userData, 'power', Math.min(vpow / 100, 100).toFixed(2))


The whole thing together would look like:

steem.api.getAccountsAsync([accountName])
  .then(function (result) {
    ...
    let secondsago = (new Date - new Date(result[0].last_vote_time + "Z")) / 1000
    let vpow = result[0].voting_power + (10000 * secondsago / 432000)
    vm.$set(vm.userData, 'power', Math.min(vpow / 100, 100).toFixed(2))  
    ...
  })


Improvements to this would be to periodically recalculate the value using a timer so that the user always sees their latest voting power (especially if they are waiting for it to tick over to 100%).

javascriptlogo.png

(Next Post: Part 4)

H2
H3
H4
3 columns
2 columns
1 column
5 Comments