Write a Steemit Web App: Part 13 - How to Calculate a Vote's RShares
(Previous Post: Part 12)
In the previous post, we calculated how much a vote was worth after it had been cast and committed to the blockchain. But, how can you determine the amount that a vote will be worth before the vote is cast (perhaps to allow the user to make an informed decision about how much voting power to use)?
Reward Shares
As we saw in the last post, each vote cast results in a "reward shares" (rshares
) being contributed by the voter. This is used to determine the percentage of the reward fund that is paid out to the author at the end of the 7 days of voting.
rshares
is calculated by the vote_evaluator
(source code) as the blockchain is processed and database updated. It uses values from multiple sources in the calculation:
First, the user's current Voting Power must be calculated. Voting Power makes each vote cast worth less than the previous vote cast, and regenerates linearly over five days (20% of a user's total Voting Power regenerates per day).
When the user casts the vote, the Vote Weight (percentage) is set. In the Condenser user interface, this is done by means of a slider that appears after clicking Upvote, unless the user has less than 500 Steem Power (and then they will not see the vote percentage slider and can only place 100% votes). Vote Weight is multiplied by Voting Power in order to determine a Weighted Voting Power.
From the Dynamic Global Properties, vote_power_reserve_rate
(10) is multiplied by the number of days represented in the STEEM_VOTE_REGENERATION_SECONDS
constant (5 days) to calculate max_vote_denom
. This appears to be a smoothing factor of sorts, to make votes worth more so long as the user is not voting more often than 10 times a day. Note: I really could use clarification of the purpose of max_vote_denom
from someone familiar with it.
Use Weighted Voting Power and max_vote_denom
as follows to calculate Used Voting Power:
used_power = (weighted_voting_power + max_vote_denom - 1) / max_vote_denom
Determine the user's effective_vesting_shares
by subtracting delegated_vesting_shares
from the account's vesting_shares
and adding in any received_vesting_shares
.
Finally, to calculate rshares
, multiply the user's effective_vesting_shares
by the Used Voting Power.
Code!
Here is a JavaScript implementation of what the Steem vote_evaluator
code performs:
const STEEMIT_VOTE_REGENERATION_SECONDS = 5 * 60 * 60 * 24; // it takes 5 days to regenerate 100% voting power
const STEEMIT_100_PERCENT = 10000
// Adjust these values to use something other than 100% for voting power and vote weight.
// Note: Value = percentage * 100, so 100% = 10000, 25.33% = 2533, etc.
const current_voting_power = STEEMIT_100_PERCENT;
const vote_pct_weight = STEEMIT_100_PERCENT;
steem.api.getAccountsAsync(["jfollas"]).then(function(results) {
const account = results[0];
const acct_vesting_shares = parseFloat(
account.vesting_shares.replace(" VESTS", "")
);
const acct_delegated_vesting_shares = parseFloat(
account.delegated_vesting_shares.replace(" VESTS", "")
);
const acct_received_vesting_shares = parseFloat(
account.received_vesting_shares.replace(" VESTS", "")
);
const effective_vesting_shares =
acct_vesting_shares -
acct_delegated_vesting_shares +
acct_received_vesting_shares;
console.log("acct_vesting_shares", acct_vesting_shares);
console.log("acct_delegated_vesting_shares", acct_delegated_vesting_shares);
console.log("acct_received_vesting_shares", acct_received_vesting_shares);
console.log("effective_vesting_shares", effective_vesting_shares);
steem.api.getRewardFundAsync("post").then(function(fund) {
const pot = parseFloat(fund.reward_balance.replace(" STEEM", ""));
const total_r2 = parseInt(fund.recent_claims, 10);
console.log("pot", pot)
console.log("total_r2", total_r2)
steem.api.getDynamicGlobalPropertiesAsync().then(function(gprops) {
const max_vote_denom = gprops.vote_power_reserve_rate * STEEMIT_VOTE_REGENERATION_SECONDS / (60*60*24);
let used_power = (current_voting_power * vote_pct_weight) / STEEMIT_100_PERCENT;
used_power = (used_power + max_vote_denom - 1) / max_vote_denom;
let rshares = effective_vesting_shares * used_power / STEEMIT_100_PERCENT;
rshares = Math.floor(rshares * 1000000)
console.log("max_vote_denom", max_vote_denom);
console.log("used_power", used_power);
console.log("rshares", rshares);
console.log("STEEM value", rshares * pot / total_r2);
});
});
});
(Next Post: Part 14)
This tutorial is awesome! long time ago I wanted to understand these small parts of the code! but the code is still complicated for me (a lot of lines to search in).
The only part that I did not understand is this:
used_power = (weighted_voting_power + max_vote_denom - 1) / max_vote_denom
max_vote_denom
is always equal to50
... means something like "50 votes are regenerated in 5 days"... because thevote_power_reserve_rate
is the number of votes regenerated per day (Source).Any ideas?
Good work. Thank you.
That part is still not very clear to me, either. That was directly taken from the C source code. When I get time, I was going to go through the history of that file to see if I could gain some insight from the series of commits that touched that line.
Hi @jfollas, I have not seen any of your posts for a while, which are so interesting.
Look, I just posted in detail how the steemit reward system works, I hope it helps.
Hi @jfollas, I read the code (I'm very tired, a lot of research), now it is more clear for me.
I posted an infographic about all this reward system, if you want to check out.
Awesome posting! Hope I saw this earlier, only one doubt, why need to
Math.floor(rshares * 1000000)
? Since I don't find this operation invote_evaluator
source code.