简介区块链技术迅猛发展,新想法、新概念、新名词层出不穷。万向区块链因此推出“技术研究报告”专栏,定期与大家分享在区块链行业创新及热门技术方面的研究成果,带领大家第一时间研究学习新技术,紧跟技术发展趋势,探索发掘技术的应用价值。
在《EOS.IO技术调研》一文中,我们分享关于EOS.IO概况、共识、出块、验证等方面的研究结果。
本文作者:万向区块链通用架构技术部 吴超尘
技术组成 | EOS.IO | |
---|---|---|
背景 | 开发团队 | BM |
成功项目 | BitShare(基于区块链技术的去中心化交易所), Steemit(基于区块链技术的社交和内容平台), EOS | |
主打功能 | TPS+WASM | |
技术 | 模块化开发 | 插件机制 (plugin) |
共识 | DPoS + Pipelined BFT | |
存储系统 | ChainBase / RocksDB | |
外部DB插件 | MongoDB, PG, Mysql | |
密码算法 | 哈希算法 | SHA2 - SHA256 |
私钥 | 32个字节的随机数,然后Base58编码 | |
公钥 | 由私钥通过ECDSA-secp256k1/r1 计算出对应的公钥 65个字节(未压缩) | |
签名算法 | SHA256 + ECDSA-secp256k1/r1 sign | |
验签算法 | ECDSA-secp256k1/r1 recove | |
应用 | 虚拟机 | WASM |
SDK | js, go | |
开发 | 开发语言 | C++ (11/14/17) |
智能合约语言 | C++ (11/14/17) | |
社区活跃度 | Github Starred 11.3k, Fork 3.7k |
DPoS (21个生产节点轮流出块,每轮出12个块, 0.5秒出1个块), 流程大概:
散户抵押之后进行投票
每轮按投票权重选出21个超级节点(BP)
BP按schedule轮流出块
区块的验证: Pipelined BFT (基于流水线的拜占庭容错机制)
成为不可逆区块: LIB(Last Irreversible Block)
链头高度和BFT共识高度之间有325个块的差距 12*(14+13)+1=325
1.选出共识节点的机制 - DPoS将账户注册为候选人
从候选人中投票选出21位区块记账者,组成超级节点列表(BP列表) (类似于选人大代表)
投票的权重会随着时间越来越小
节点定时更新BP列表的流程:
步骤一: nodeos出块时调合约内的方法onblock:
nodeos
on_block_act.name = N(onblock);
eos_abi.structs.emplace_back( struct_def {
"onblock", "", {
{"header", "block_header"}
}
});
eos_abi.actions.push_back( action_def{name("onblock"), "onblock",""} );
contract
[[eosio::action]]
void onblock( ignore header );
步骤二: BP合约内容更新时 回调nodeos本地函数接口
onblock合约方法内限制间隔1分钟才会调此方法进行统计选票
update_elected_producers
决定出最新的21个BP后, 再设置回nodeos(节点)的接口 set_proposed_producers
, 发出 promoting proposed schedule
set_proposed_producers
步骤三: 从promoting proposed schedule
到pending schedule
再到active schedule
当包含promoting proposed schedule
的块进入LIB后,BP会陆续更新自己block header中的pending schedule
等到2/3 +1个BP节点都已经更新block header后,pending schedule
达成共识。BP会陆续将active schedule
更新为此时pending schedule
的值,并按照新的BP组合开始出块,整个过程需要至少经过两轮完整的出块。
每一次新的BP组合,一定要能够达成共识才能真正生效。换句话说,如果网络中7个或更多节点无法正常通信,那么无论如何不能通过投票的方式产生新的BP。网络的LIB会一直停留在节点崩溃的那个共识点。
2.出块机制出块间隔 0.5 秒
每个超级节点每轮连续出12个块,21*12个块算一轮,每轮结束,重新计算选票,选出新的超级节点列表
Block Producing Explained | EOSIO Developer Docs
一个BP连续出12个块, 相对而言在此6秒内能比较稳定的出块, 只在2个BP交替的第13个块, 后一个BP可能会有跟不上的风险
如果在某个时间内没有成功出块,则跳过该块 (在最近24小时内没有产生任何块,则这个出块者将被删除)
出块流程
3.区块验证机制 - Pipelined BFTEOS的特殊BFT (采用的是基于流水线的拜占庭容错机制)
常规的PBFT是生产一个区块,等待共识,然后再生产一个区块。21个共识节点时, 由于PBFT共识两轮投票需要较长的时间,因而不容易满足0.5s出块需求。因而EOS的BFT采取了不同的实现方式,出块和共识是流水并行工作的,区块生产完成后,不等待BFT共识,继续生产同时参与并处理上一个区块的BFT共识,当BFT共识完成后即修改为不可逆状态。
假设: 共4个BP, 一次生产一个块
EOS中,21个生产节点轮流出块。一个区块是通过后续节点基于该区块的生产行为来间接确认的,为了实现BFT级别的不可逆,需要得到两轮2/3+1
的节点确认。区块的确认分为两个阶段:
第一个阶段是prepare
阶段,该阶段需要接受2/3+1
个节点的确认。由于每个节点生产12个区块,所以需要12*(2/3*21+1)=12*15=180
个区块确认。
第二个阶段是commit
阶段, 也需要2/3+1
个节点的签名确认。因为经过prepare
阶段之后, 还不能确定绝大多数节点都已经了解到这轮2/3的确认信息。因而还需要一轮2/3的确认, 好180个块。
然而,如果大家在EOS区块链上查询区块的实时信息,就会发现一个区块需要经过的是325个区块, 之后会被标识为不可逆状态。块数: 12*14 + (12*13 + 1) = 12*(14+13)+1 = 325
4.比较解释: 整个网络共21个超级节点, 那么需要15个人(BP)确认才能达成一轮共识。每个人默认会对自己出的块进行确认,所以每个块需要14个人的确认就能完成一轮共识。同理第二轮也需要14个BP, 但最后第14个BP出第一个块时,共识共识即可完结, 而不用等它出完自己连续的12个块. 所以一个块从它产生后,要到之后的第28个BP所产出的第一个块时才能得到全网共识,进入LIB。因此有以上计算。
POA 与 DPoS 的比较
POA | DPoS | |
---|---|---|
适用场景 | 私链或者联盟链 | 公链 |
候选节点 | 作为提案直接指定 | 任何链上账户都可以注册为候选节点 |
票哪里来 | 一个共识节点一票 | 抵押原生兑换物, 获得票数 |
票的权重 | 无/或者认为是不变的 | 选票的权重会随着时间而衰退*,除非重新投票 (可以确保更积极的治理 DAO) |
成为共识节点 | 得到大多数现有共识节点的同意 | 获得选票最高的前21个节点 |
共识节点数量 | 没有限制 | 最多21个 |
移除共识节点组 | 得到大多数现有共识节点的同意 | 每轮都会重新计票 |
*权重衰退的发生率约为每周1%。这意味着,在一年的过程中,如果不更新投票,账户的投票权重将减少约一半
PBFT 与 DPoS - Pipelined BFT 的比较
PBFT | DPoS - Pipelined BFT | |
---|---|---|
适用场景 | 联盟链 | 公链 |
view change | 更换primary节点的过程 | BP schedule发生变更 |
pre-prepare | primary节点收到请求,广播给网络里的所有replica | BP出块并广播至全网 |
prepare | replica收到pre-prepare请求后向全网广播将要对此请求进行执行 | 所有节点收到块并验证成功后广播已收到的信息 |
commit | replica收到足够多的对同一请求的prepare消息,向全网广播执行此请求 | 节点收到足够多基于某一个块之后出的块, 提出proposed lib消息 |
committed-local | replica收到足够多对同一请求的commit消息, 完成了验证工作 | LIB Number 变更 |
checkpoint | 固定k个请求后生成 | BP schedule发生变更的块(至少两轮完整的出块过程) |
5.避免分叉checkpoint: 指在某一个块高度记录共识证据, 以此来提供安全性证明. 当足够多的replica的checkpoint相同时, 这个checkpoint被认为是stable的. 可以清理stable checkpoint之前的共识数据, 避免内存占用过大
区块创造过程对分叉的检测
检查区块生产者的合法性
如果当前主干已经不是最长链,需要切换到最长的分叉链上切换过程如下
d出一定数量的区块,直到碰到分叉处
将分叉中的新区块写入主干数据库
切换后的分叉成为主干
如果上述过程失败,则恢复状态
如果不需要切换分支,则往主干数据库中写入区块
返回结果,以表明这次写入是否造成了分支切换
还未成为不可逆的区块,可能会分叉, 共识将自动切换到最长的链条。具有更多生产者的区块链长度将比具有较少生产者的区块链增长速度更快。
经过Pipelined BFT共识验证过的区块不会再分叉
块生产者不应该同时在两条分叉链上都生产块。一旦被发现,就可能被投票出局
6.共识协议升级机制 (DAO)投票率达到15%,激活DPoS共识
需要获得绝大多数区块生产者的批准, 才能激活新的协议
cleos push transaction '{"delay_sec":0,"max_cpu_usage_ms":0,"actions":[{"account":"eosio","name":"activate","data":{"feature_digest":"299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707"},"authorization":[{"actor":"eosio","permission":"active"}]}]}'
链激活后
eosio
将owner和active权限转移给eosio.prods
(这是个权限由21个超级节点控制的多签账户)
所有eosio.*
账户将owner和active权限转移给eosio
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)