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——软件项目风险管理及解决办法案例 摘要 软件项目风险是指在软件开发过程中遇到的预算和进度等方面的问题以及这些问题对软件项目的影响.软件项目风险会影响项目计划的实现,如果项目风险变成现实, ...
随机推荐
- The lesser known pitfalls of allowing file uploads on your website
These days a lot of websites allow users to upload files, but many don’t know about the unknown pitf ...
- MySQL启动失败解决办法
本人大二,进了一家培训机构学了两年,然后跟着他们做项目,其实也是练习,然后过程中遇到好多错误,当时解决了,然后下次遇到又忘了,-_-! -_-||| 我就想通过写博客来记载一下我遇到的错误和解决的办 ...
- oracle connect by用法篇 (包括树遍历)之一
1.基本语法 select * from table [start with condition1] connect by [prior] id=parentid 一般用来查找存在父子关系的数据,也就 ...
- ABP缓存
简介 缓存是做什么的? 简单的可以认为是一个键值对的数据存于内存中,高速读取.作用为了减少和数据库的交互 Abp中缓存的使用 public class InvoiceAppService : Appl ...
- js中的操作符
写在前面 js语法 DOM对象(把body,div,p等节点树看成一个对象) BOM对象(把浏览器的地址栏历史记录DOM等装在一个对象) 浏览器是宿主,但js的宿主不限于浏览器,也可以是服务器,如no ...
- android手机分辨率的一些说明
Android上常见度量单位 px(像素):屏幕上的点,绝对长度,与硬件相关 in(英寸):长度单位 mm(毫米):长度单位 pt(磅):1/72英寸,point dp(与密度无关的像素):一种基于屏 ...
- 奇葩问题 eclipse下 maven项目 java Resource报个小红叉,然而里面却没有小红叉
之前没注意,不知是一开始就有还是这两天才有,说下解决方案: 右击项目“Properties”,在弹出的“Properties”的左侧边框,单击“Project Facets”,打开“Project F ...
- GUI编程01
1 tkinter TkInter是标准的Python GUI库.的Python与Tkinter的结合提供了一个快速和容易的方法来创建GUI应用程序. Tkinter的提供了一个强大的面向对象的接口T ...
- pthread多线程编程
http://blog.csdn.net/onlyou930/article/details/6755593 http://blog.csdn.net/ithomer/article/details/ ...
- loj10241 取石子游戏1
传送门 分析 我们发现如果在某个人取完之后还剩k+1个石子,则这个人必胜.所以我们可以将n个石子转化为n-k-1个,然后不断递归的转化下去.最后我们可以得到对于n个石子的胜负只与谁先取到n%(k+1) ...