eos有个核心理念,EOS代币的所有者给予用户按比例的网络带宽、存储空间、运算能力。好处是用户拥有1%的EOS代币,无论网络其余部分的负载如何,他将始终可以访问1%的网络带宽。恶意攻击者只能消耗根据其EOS代币占比拥有的相应比例的网络资源。不会影响整个eos网络。

本文目的是分析eos这一核心理念是如何实现的?

根据eos官网找到了代码实现的范围
https://github.com/EOSIO/eos/tree/master/contracts/eosio.system

eosio.system是EOS的智能合约,eos三个核心功能:
1,用户抵押token,可以投票给区块生成者(block producer),就是目前竞争火热的21个超级节点,还有获得社区提案(worker proposal)的权利。
2,设置代理,把投票权移交给其他用户。
3,抵押token,获得相应的网络带宽,存储空间,运算能力。

部署合约:

首先需要创建个钱包,才可以做其它操作

创建默认钱包

./cleos wallet create

设置基础配置智能合约:eosio.bios

./cleos set contract eosio ../../contracts/eosio.bios -p eosio -j

设置系统智能合约:eosio.system 部署了该智能合约

cleos set contract eosio ../../contracts/eosio.system -p eosio

然后才可以有账户发行EOS token,才可以执行,注册producer,投票者下注,投票等操作。

创建eos token

./cleos push action eosio issue '{"to":"eosio","quantity":"1000000000.0000 EOS"}' --permission eosio@active -j

创建账户 bp.a

./cleos create account eosio bp.a EOS8dtXWZQWqSv4mk3WPrpMKGywA5pBY1MWxbpSGSLVvV4k98kvxs EOS7fhfs1j5BBQC9bsM5c8c2WZy6NPG6mbAGMuuYJCnKNHfb3vrND

vo.a 押token

./cleos push action eosio delegatebw '{"from":"vo.a","receiver":"vo.a","stake_net":"100.0000 EOS","stake_cpu":"100.0000 EOS","stake_storage":"0.0000 EOS"}' --permission vo.a@active

vo.a给 bp.a 投票

./cleos push action eosio voteproducer '{"voter":"vo.a","proxy":"","producers":["bp.a"]}' --permission vo.a@active

eosio.system合约源码

1,eosio.system合约的主要代码在eosio.system.hpp、eosio.system.cpp两个文件中;
2,eosio.system合约有很多Action,eosio.system.cpp中的EOSIO_ABI宏定义如下:

EOSIO_ABI( eosiosystem::system_contract,(setram)// delegate_bandwith.cpp(delegatebw)(undelegatebw)(refund)(buyram)(buyrambytes)(sellram)// voting.cpp// producer_pay.cpp(regproxy)(regproducer)(unregprod)(voteproducer)(claimrewards)// native.hpp(onblock)(newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay)
)

3,可以看到,具体的Action实现代码分散到了delegate_bandwith.cpp、voting.cpp、producer_pay.cpp、native.cpp中,下面会进行分析。

4、eosio.system.hpp中定义了合约类eosiosystem::system_contract,和一些结构体:

eosio_global_state(全局状态)
producer_info(生产者信息)
voter_info(投票人信息)

5,system_contract类继承自native.hpp中定义的eosiosystem::native类,native类又继承自eosio::contract基类;

6,system_contract类中定义了system合约的Action,

tapos_block_num() 返回目前区块的高度,区块的总数量

以下Action在producer_pay.cpp中实现:

计算生产者节点收益的相关代码://计算一些遗漏的区块,更新指定生产者的区块信息  //每次生产区块就会执行。
//onlock函数在每次生产者出块的时候都会被调用,见证者收到区块后也会调用(相当于验证区块),每次生产者出块都会把该生产者的出块数进行统计,把所有的区块也进行统计
void onblock( uint32_t timestamp_slot, account_name producer );//(生产者)获取回报奖励
void claimrewards( const account_name& owner );//计算根据生产者生产的区块数量,计算每个块的收益
eosio::asset system_contract::payment_per_block( double rate, const eosio::asset& token_supply,  uint32_t num_blocks ) {
const int64_t payment = static_cast<int64_t>( (rate * double(token_supply.amount) * double(num_blocks)) / double(blocks_per_year) );
return eosio::asset( payment, token_supply.symbol );
}//计算根据生产者的生产时间,计算每秒收益
eosio::asset system_contract::supply_growth( double rate, const eosio::asset& token_supply, time seconds ) {
const int64_t payment = static_cast<int64_t>( (rate * double(token_supply.amount) * double(seconds)) / double(seconds_per_year) );
return eosio::asset( payment, token_supply.symbol );
}//计算生产者从每次投票中获得的收益(代码部分省略)
eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ) {
eosio::asset payment(0, S(4,EOS));
//如果每日收益少于100EOS,则没有收益
const int64_t min_daily_amount = 100 * 10000;
if ( pervote_bucket.amount < min_daily_amount ) {return payment;
}
//省略...
return payment;
}先理清一下概念:_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用户下,但又马上转给了生产者,这样的设计暂时没有弄明白(为什么不直接转帐给生产者)。

以下Action在delegate_bandwidth.cpp中实现:

  //抵押token,获取网络和CPU资源//from是抵押者,receiver是token接收者//transfer如果设置为true,接收者可以取消抵押,否则抵押者可以随时取消抵押void delegatebw(account_name from, account_name receiver,asset stake_net_quantity, asset stake_cpu_quantity, bool transfer);//取消抵押,释放网络和CPU资源
//from取消抵押后,会失去投票权
void undelegatebw(  account_name from, account_name receiver,asset unstake_net_quantity, asset unstake_cpu_quantity );//购买指定价值内存,buyer是购买者,receiver是内存接收者
void buyram( account_name buyer, account_name receiver, asset tokens );//购买指定大小的内存,支付的EOS会以当前市场价格计算
void buyrambytes( account_name buyer, account_name receiver, uint32_t bytes   );//出售内存
void sellram( account_name receiver, uint64_t bytes );//取回token,有3天等待期
void refund( account_name owner );

实现的主要是和资源分配有关的Action:

//抵押token,获取网络和CPU资源
//from是抵押者,receiver是token接收者
//transfer如果设置为true,接收者可以取消抵押,否则抵押者可以随时取消抵押
void delegatebw(account_name from, account_name receiver,asset stake_net_quantity, asset stake_cpu_quantity, bool transfer);//取消抵押,释放网络和CPU资源
//from取消抵押后,会失去投票权
void undelegatebw(  account_name from, account_name receiver,asset unstake_net_quantity, asset unstake_cpu_quantity );//购买指定价值内存,buyer是购买者,receiver是内存接收者
void buyram( account_name buyer, account_name receiver, asset tokens );//购买指定大小的内存,支付的EOS会以当前市场价格计算
void buyrambytes( account_name buyer, account_name receiver, uint32_t bytes );//出售内存
void sellram( account_name receiver, uint64_t bytes );//取回token,有3天等待期
void refund( account_name owner );

以下Action在voting.cpp中实现

//注册生产者,会为生产者创建或更新producer_info对象void regproducer( const account_name producer, const public_key& producer_key, const std::string& url );//取消注册void unregprod( const account_name producer );//投票,可以投给多个生产者
void voteproducer( const account_name voter, const account_name proxy, const std::vector<account_name>& producers );//注册成为投票代理
//已经使用了代理的投票者,不能注册为投票代理
void regproxy( const account_name proxy, bool isproxy );

voting.cpp中包含了投票相关的Action,比较重要的有:

//根据投票数由高到低,选出21个区块生产者,并更新数据
void system_contract::update_elected_producers( block_timestamp block_time ) {
//...
}//用户投票选出生产者
//参数voter_name表示投票人,proxy表示该账户的代理人
//参数producers是一个生产者数组
void system_contract::voteproducer( const account_name voter_name, const account_name proxy, const std::vector<account_name>& producers ) {//如果已有代理人,表示该账户已经把投票权委托出去了,就不能再投票
if ( proxy ) {eosio_assert( producers.size() == 0, "cannot vote for producers and proxy at same time" );//不能委托给自己eosio_assert( voter_name != proxy, "cannot proxy to self" );require_recipient( proxy );
} else {//一次不能投超过30个生产者eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" );//检测账户投的生产者列表中的节点是否是唯一且排好序的for( size_t i = 1; i < producers.size(); ++i ) {eosio_assert( producers[i-1] < producers[i], "producer votes must be unique and sorted" );}
}auto voter = _voters.find(voter_name);
//需要抵押token才能投票
eosio_assert( voter != _voters.end(), "user must stake before they can vote" );
//已注册为代理人的账户,不能再委托别人进行投票
eosio_assert( !proxy || !voter->is_proxy, "account registered as a proxy is not allowed to use a proxy" );//省略...
}

eosio.system合约分析相关推荐

  1. EOS智能合约开发(十)EOS中eosio.token合约分析

    前面文章里,我们部署过eosio.token合约,今天我们就分析一下这个合约. 首先,我们部署eoiso.token合约,通过这个合约,可以创建不同的token,可以由不同的账户部署管理这个合约.所有 ...

  2. system合约源码分析

    写在前面 system合约是EOS区块链最核心的智能合约,分析其源码可以一窥EOS的精妙之处. 文件结构 native 基础的数据结构和功能 delegate_bandwidth 带宽抵押与内存买卖 ...

  3. EOS 智能合约源代码解读 (14)system合约“exchange_state.hpp”

    1. 使用bancor数学创建一个在两种资产类型中的50/50的中继 namespace eosiosystem {using eosio::asset;using eosio::symbol;typ ...

  4. 理解eos区块链的eosio.token合约

    2019独角兽企业重金招聘Python工程师标准>>> 我必须承认,学习eosio一直没有闲庭信步的感觉,我可以看到为什么很多人说它有一个陡峭的学习曲线.随着eosio软件继续经历大 ...

  5. Android A/B System OTA分析(三)主系统和bootloader的通信

    Android从7.0开始引入新的OTA升级方式,A/B System Updates,这里将其叫做A/B系统,涉及的内容较多,分多篇对A/B系统的各个方面进行分析.本文为第三篇,主系统和bootlo ...

  6. Android A/B System OTA分析(六)如何获取 payload 的 offset 和 size

    本文为洛奇看世界(guyongqiangx)原创,转载请注明出处. 文章链接:https://blog.csdn.net/guyongqiangx/article/details/72604355 A ...

  7. Android A/B System OTA分析(四)系统的启动和升级

    Android从7.0开始引入新的OTA升级方式,A/B System Updates,这里将其叫做A/B系统,涉及的内容较多,分多篇对A/B系统的各个方面进行分析.本文为第四篇,系统的启动和升级. ...

  8. Android A/B System OTA分析(五)客户端参数

    本文为洛奇看世界(guyongqiangx)原创,转载请注明出处. 文章链接:https://blog.csdn.net/guyongqiangx/article/details/122430246 ...

  9. Android A/B System OTA分析(一)概览

    本文为洛奇看世界(guyongqiangx)原创,转载请注明出处. 文章链接:https://blog.csdn.net/guyongqiangx/article/details/71334889 A ...

最新文章

  1. Python游戏开发,pygame模块,Python实现愤怒的小鸟【附带源码】
  2. seo模拟点击软件_网站用软件刷排名好不好?
  3. freebsd 手工安装zabbix2.0 php,zabbix 服务端,子客户端安装配置日志
  4. oc调用rest api
  5. nssl1467-U【差分】
  6. 具有Tron效果的JavaFX 2 Form
  7. Unity Scene为每一个游戏物体进行扩展编辑
  8. Linux 进程信号详细总结
  9. 技术出身要创业,容易吗?
  10. 哈希表中处理冲突的方法
  11. java学生签到系统_学生签到系统.pdf
  12. 数​据​库​查​看​内​存​使​用​I​N​F​O​R​M​I​X
  13. HMC5883L电子罗盘/指南针实现,附带校准方法(附STM32 源码)
  14. WebRTC系列--视频编码控制之BALANCED(分辨率与帧率平衡模式)
  15. 硬核拆台!宏彦获水,一脸懵逼:百度李彦宏遭当众泼水,一开始肇事者就在全程直播!!
  16. TEEOS的实例-在线支付系统
  17. (阿里巴巴开发手册)为什么阿里巴巴推荐内部员工使用StringBuilder?
  18. 斑马GK888T打印机跑纸(打印半张以及闪红灯)解决办法
  19. Python-loss和acc曲线分析
  20. 校园防疫管理系统功能详解,请查看

热门文章

  1. js——form表单验证
  2. 台式机进入bios后显示器无法显示
  3. 常用linux的37个命令
  4. 有趣python小程序系列之二
  5. java后台获取和js拼接展示信息
  6. 园区——论开发商与运营商的盈利模式
  7. 【蓝桥杯JavaB组真题详解】振兴中华(2013)
  8. 不规则图形数格子的方法_方格图中不规则图形的面积计算
  9. 人机料法环,最全质量管理方法都在这儿!
  10. Windows10专业版1803_64位2018.11(装机版)