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——软件项目风险管理及解决办法案例 摘要 软件项目风险是指在软件开发过程中遇到的预算和进度等方面的问题以及这些问题对软件项目的影响.软件项目风险会影响项目计划的实现,如果项目风险变成现实, ...
随机推荐
- JCTF 2014(Misc)
小试身手: 点击下载附件 res/raw/hehe,打开 得到flag
- typescript相关知识点总结
本文讲解typescript语法 由于js语法本身的混乱,再加上目前框架的割据,导致typescript用起来没有一致性,本文尽量总结实际开发中可能会用到的知识点 目录 数据类型 类型断言 duck ...
- 10-12C#基础--运算符
10-12C#基础--运算符 课前作业:班级内人数的姓名和年龄,分别写出之后并汇总. 一.运算符的分类 1.数学运算符(7个) 1)+(加号) 例: 2)-(减号) 例: 3)*(乘号) 例: 4)/ ...
- Linux 2.6 中的文件锁
简介: 本文的目的是想帮助读者理清 Linux 2.6中文件锁的概念以及 Linux 2.6 都提供了何种数据结构以及关键的系统调用来实现文件锁,从而可以帮助读者更好地使用文件锁来解决多个进程读取同一 ...
- CUDA编程接口:异步并发执行的概念和API
1.主机和设备间异步执行 为了易于使用主机和设备间的异步执行,一些函数是异步的:在设备完全完成任务前,控制已经返回给主机线程了.它们是: 内核发射; 设备间数据拷贝函数; 主机和设备内拷贝小于64KB ...
- hibernate学习笔记(3)hibernate常用配置以及session对象
更改hibernate.cfg.xml的内容,常用配置有: <!-- 把hibernate运行时的SQL语句显示到控制台 --> <property name="sho ...
- springmvc 处理器方法返回的是modelandview 重定向到页面
- sh 脚本重启/更新 Tomcat 项目
一.项目文件为一个 jar 包,无须解压 重启 Tomcat 项目 #!/bin/bash echo "kill hot-jdt" kill -9 `ps -ef|grep hot ...
- 第4章 ZK基本特性与基于Linux的ZK客户端命令行学习 4-2 session的基本原理与create命令的使用
客户端与服务端之间存在的连接,那么这样的一个连接我们就称之为会话,也就是session.其实就相当于是我们在做JSP或者说是Service的时候,那么服务端是Servlet,客户端使用的是浏览器.浏览 ...
- 【安装关键】webStorm-201703版本
在激活页面选择License Server,输入:http://idea.codebeta.cn,点击Activate即可激活.