EOS 增发与生产者的奖励制度
EOS每年增发1%的机制在系统合约中,其实说每年增发1%只是一年的总数,其实是只要在出块,EOS就在增发的路途中,下面分析一下增发的代码。
其实增发的1%的都是分给所有区块生产者的,只要出块了或者获得投票都有奖励,代码在producer_pay.cpp文件中,只有下面两个函数。
void system_contract::onblock( block_timestamp timestamp, account_name producer ) {
using namespace eosio;
require_auth(N(eosio));
/** until activated stake crosses this threshold no new rewards are paid */
if( _gstate.total_activated_stake < min_activated_stake )
return;
if( _gstate.last_pervote_bucket_fill == ) /// start the presses
_gstate.last_pervote_bucket_fill = current_time();
/**
* At startup the initial producer may not be one that is registered / elected
* and therefore there may be no producer object for them.
*/
auto prod = _producers.find(producer);
if ( prod != _producers.end() ) {
_gstate.total_unpaid_blocks++;
_producers.modify( prod, , [&](auto& p ) {
p.unpaid_blocks++;
});
}
/// only update block producers once every minute, block_timestamp is in half seconds
if( timestamp.slot - _gstate.last_producer_schedule_update.slot > ) {
update_elected_producers( timestamp );
if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) {
name_bid_table bids(_self,_self);
auto idx = bids.get_index<N(highbid)>();
auto highest = idx.begin();
if( highest != idx.end() &&
highest->high_bid > &&
highest->last_bid_time < (current_time() - useconds_per_day) &&
_gstate.thresh_activated_stake_time > &&
(current_time() - _gstate.thresh_activated_stake_time) > * useconds_per_day ) {
_gstate.last_name_close = timestamp;
idx.modify( highest, , [&]( auto& b ){
b.high_bid = -b.high_bid;
});
}
}
}
}
这个onlock函数在每次生产者出块的时候都会被调用,见证者收到区块后也会调用(相当于验证区块),每次生产者出块都会把该生产者的出块数进行统计,把所有的区块也进行统计,后面的代码不太清楚在做什么,后续再补充。
void system_contract::claimrewards( const account_name& owner ) {
require_auth(owner);
const auto& prod = _producers.get( owner );
eosio_assert( prod.active(), "producer does not have an active key" );
eosio_assert( _gstate.total_activated_stake >= min_activated_stake,
"cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)" );
auto ct = current_time();
eosio_assert( ct - prod.last_claim_time > useconds_per_day, "already claimed rewards within past day" );
const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() );
const auto usecs_since_last_fill = ct - _gstate.last_pervote_bucket_fill;
if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > 0 ) {
auto new_tokens = static_cast<int64_t>( (continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) );
auto to_producers = new_tokens / 5;
auto to_savings = new_tokens - to_producers;
auto to_per_block_pay = to_producers / 4;
auto to_per_vote_pay = to_producers - to_per_block_pay;
INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}},
{N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} );
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)},
{ N(eosio), N(eosio.saving), asset(to_savings), "unallocated inflation" } );
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)},
{ N(eosio), N(eosio.bpay), asset(to_per_block_pay), "fund per-block bucket" } );
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)},
{ N(eosio), N(eosio.vpay), asset(to_per_vote_pay), "fund per-vote bucket" } );
_gstate.pervote_bucket += to_per_vote_pay;
_gstate.perblock_bucket += to_per_block_pay;
_gstate.last_pervote_bucket_fill = ct;
}
int64_t producer_per_block_pay = 0;
if( _gstate.total_unpaid_blocks > 0 ) {
producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks;
}
int64_t producer_per_vote_pay = 0;
if( _gstate.total_producer_vote_weight > 0 ) {
producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight);
}
if( producer_per_vote_pay < min_pervote_daily_pay ) {
producer_per_vote_pay = 0;
}
_gstate.pervote_bucket -= producer_per_vote_pay;
_gstate.perblock_bucket -= producer_per_block_pay;
_gstate.total_unpaid_blocks -= prod.unpaid_blocks;
_producers.modify( prod, 0, [&](auto& p) {
p.last_claim_time = ct;
p.unpaid_blocks = 0;
});
if( producer_per_block_pay > 0 ) {
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.bpay),N(active)},
{ N(eosio.bpay), owner, asset(producer_per_block_pay), std::string("producer block pay") } );
}
if( producer_per_vote_pay > 0 ) {
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.vpay),N(active)},
{ N(eosio.vpay), owner, asset(producer_per_vote_pay), std::string("producer vote pay") } );
}
}
} //namespace eosiosy
先理清一下概念:
_gstate.pervote_bucket //所有生产者获得投票的奖励资金
_gstate.perblock_bucket //所有出块的奖励资金
_gstate.total_unpaid_blocks //公链上还没有领取出块奖励的所有区块数
这里的做法是:
1.每个生产者至少每隔一天可以领取奖励;
2.出块的资金数目分为两部:把20%当做奖励发放给生产者;把80%放在了系统用户eosio.saving下面。
3.资金池为总数的20%,每个生产者领取的奖励计算方式: 生产者出块数 / 所有未领取奖励的区块数 * 25% + 生产者获得的投票数 / 公链上所有的投票数 * 75%(25%和75%的比例是指奖金池的比例)
4.因为是增发,所有eosio用户也会同步发行同等代币(总数的20%,);
5.出块的奖励资金会临时放在系统用户eosio.bpay下, 获得的投票收益临时放在eosio.vpay用户下,但又马上转给了生产者,这样的设计暂时没有弄明白(为什么不直接转帐给生产者)。
EOS 增发与生产者的奖励制度的更多相关文章
- EOS多节点组网:商业场景分析以及节点启动时序
区块链公链都是基于p2p网络,本篇文章将建立一个多节点不同职责参与的EOS的测试网络,根据路上发现的可做文章的技术点大做文章. 关键字:EOS组网,全节点,交易确认,boot sequence,sta ...
- eos bp节点 超级节点搭建
搭建eos BP节点 环境搭建与配置 安装最新版本 $ wget https://github.com/eosio/eos/releases/download/v1.8.1/eosio-1 ...
- 如何成为一位优秀的创业CEO
英文原文:How to Be Startup CEO 编者按:本文来自 Ryan Allis,是一位来自旧金山的创业者和投资人.在 2003 年创立了 iContact,并任 CEO. 做创业公司的 ...
- 高薪诚聘.NET MVC开发工程师
你想有大好的发展前途吗?你想拥有高的月薪吗? 赶快来吧! 1.企业网站.电子商务开发: 2.进行详细设计.代码开发,配合测试,高质量完成项目: 3.参与技术难题攻关.组织技术积累等工作. 任职资格: ...
- PKM(personal knowledge management)
内化 一般含义 一般上,当涉及道德行为时,内化是巩固和植入某人信念.态度和价值的长期过程,而这一过程的实现牵扯到精神分析或行为方法的慎重使用. 当改变道德行为时,一组新的信念.态度和价值代替或适应于所 ...
- 2012高校GIS论坛
江苏省会议中心 南京·钟山宾馆(2012年4月21-22日) 以"突破与提升"为主题的"2012高校GIS论坛"将于4月在南京举行,由南京大学和工程中心共同承办 ...
- 【转】如何成为一位优秀的创业CEO
编者按:本文来自 Ryan Allis,是一位来自旧金山的创业者和投资人.在 2003 年创立了 iContact,并任 CEO. 做创业公司的 CEO 可以说是世界上最有挑战性的事情之一.你得让客户 ...
- 【项目管理】 项目管理术语总结 (PMP培训笔记)
1. 项目管理简介 (1) 项目管理定义 项目管理定义 : 将 知识, 技能, 工具 与 技术 应用与项目活动, 以满足项目的要求; (2) 现代项目管理 现代项目管理与传统项目管理区别 : -- 传 ...
- 小账本APP——软件项目风险管理及解决办法案例
小账本APP——软件项目风险管理及解决办法案例 摘要 软件项目风险是指在软件开发过程中遇到的预算和进度等方面的问题以及这些问题对软件项目的影响.软件项目风险会影响项目计划的实现,如果项目风险变成现实, ...
随机推荐
- linux串口基本编程
Linux的串口表现为设备文件.Linux的串口设备文件命名一般为/dev/ttySn(n=0.1.2„„),若串口是USB扩展的,则串口设备文件命名多为/dev/ttyUSBn(n=0.1.2„„) ...
- MyBatis----延迟加载demo
一:创建数据库脚本drop table project_info; drop table status; create table status( id number(10) primary key, ...
- hibernate 单元测试
单元测试 测试 dao service action package com.kaishengit.test; import org.hibernate.Session; import com.ka ...
- How to recover destroyed ZFS storage pools
root@sol11ai:~# zpool status tank pool: tank state: ONLINE scan: resilvered 91K in 0h0m with 0 e ...
- (转)newInstance()和new()
在Java开发特别是数据库开发中,经常会用到Class.forName( )这个方法.通过查询Java Documentation我们会发现使用Class.forName( )静态方法的目的是为了动态 ...
- javascript的概述
JavaScript是怎么诞生的???刚开始的是为了验证表单而开发出来的. 什么是JavaScript???a.面向对象的编程语言b.解释性的编程语言(说白了就是不用编译的一种语言)c.脚本语言(说白 ...
- nodejs的POST请求
http://blog.csdn.net/puncha/article/details/9015317 Nodejs 发送HTTP POST请求实例 2013-06-03 17:55 71745人阅读 ...
- PDF的一些工具
PdfStreamDumper Pdftk 这里有一个链接,列出了很多pdf免费工具 https://en.wikipedia.org/wiki/Category:Free_PDF_software ...
- Linux如何修改网络环境参数
如下设置: 检验是否可以连通,就使用ping命令ping 网关开始的时候总是现实unreachable 设置IP:sudo ifconfig eth0 133.133.133.190 netmask ...
- Evil Book -- CodeChef
传送门 分析 对于这道题,我们首先思考一个贪心策略,即对于所有我们要打败的厨师我们肯定可以先打败需使用帮助次数少的厨师再打败需使用帮助次数多的厨师 ,因为这样可以使得能支付得起帮助费用的可能性尽可能的 ...