0%

ETH五---以太坊中的共识机制

以太坊中的共识机制

​ 以太坊把出块时间降低到了十几秒,和比特币相比,以太坊的出块速度相当于提高了40倍,但是降低出块时间之后也带了一些新的问题:比特币和以太坊都是运行在应用层的共识协议,它的底层都是使用p2p overlay network,这个network本身传输的时间是比较长的,因为它的拓扑协议做flooding的时候是没有考虑实际的拓扑结果,这就带来一个问题,你发布一个区块之后,区块在网络上传到其他节点可能需要十几秒的时间,对于比特币来说,十分钟的出块时间相当于600秒,这个是足够让新发布的区块传播到网上的其他节点的,当然,即使这样,因为挖矿是个概率的过程,所以仍然有可能是有两个矿工同时获得记账权,同时发布区块,这种情况会带来临时性的分叉,那么对于以太坊来说,这种临时性的分叉就会变成常态,而且分叉的数目也会更多,这对于共识协议来说,有什么挑战呢?

比特币的情况:只有在最长合法链上的那些区块的出块奖励才是真正有用的。因为对于出现临时性分叉的情况不是很多,所以这么规定还是可以接受的。

如果以太坊也这么处理,意味着这个矿工所挖到的区块有很大的概率可能是白挖了,可能你挖出的区块最终没有成为最长合法链,这样对矿工来说,不是很公平(尤其是对于个体矿工;挖矿的两大趋势:设备的专业化,矿池的出现),正常情况下,我们希望的情况是,矿池能够得到的收益应该和你的算力比例是相关的(公平),但是如果共识协议设计不好的话,有可能大型矿池的收益比例大于它所占的算力比例(会出现恶行循环),中心化mining centralization 带来的不成比例的优势centralization bias,所以如果以太坊沿用比特币的共识协议,是会有很大的问题的

uncle block

​ 以太坊中采用了GHOST协议的共识机制,GHOST的出现比以太坊早,以太坊对这个协议做了修改,这个协议的核心思想是:你挖到了矿,发布了一个区块,这个区块最后作废了,你挺伤心的,我们给你一些安慰,给你一些奖励,这种时候你也能得到一些出块奖励

​ 为什么叫uncle block?

因为它跟当前最长合法链上的区块来说,这个区块是它的叔父区块(和它的父亲是一个辈分的),最长合法链上的区块在发布的时候,可以把它的叔父区块包含进来,在这个区块发布的时候,它的叔父区块可以获得7/8的出块奖励,这个区块能得到额外的1/32(每包含一个,就得到额外的1/32)的出块奖励,一个区块最多可以包含两个叔父区块

​ 以太坊的出块奖励刚开始的时候,是5个以太币,17年下半年的时候改了,改成3个以太币。这样设计,有利于鼓励系统中出现分叉之后及时进行合并,相当于新发布的区块把它的叔父区块招安过来了,这是Ghost协议最初的版本。

​ 最初版本的协议有没有什么缺陷?

①只能包含两个叔父区块,如果出现第三个怎么办?

②如果这个矿工比较自私的话,他有可能故意不把叔父区块包含进去:这样对于叔父区块来说7/8的出块奖励就得不到了,因为矿池之间有竞争关系,所以有的矿池就故意这么做

有竞争关系的区块不包含叔父区块没有关系,但是你不包含,别人会包含,下一个区块就不一定是你挖出来的,也可能是自己来挖,把自己当作叔父区块包含进来

​ 本质:我们为了改进最初版本的ghost协议存在一些问题,所以我们把叔父的定义扩展了,不一定是当代叔父,可能是隔了几代的叔父,但是问题是隔了多少代?是不是可以隔一百代?那我就在很久很久以前,挖矿难度比较低的时候不断地产生叔父区块,期待着被包含。

​ 以太坊中的规定:

​ 这样设置有什么好处?如果不这样设计会有什么坏处

首先,如果你不限制叔父的辈分,那么这个实现起来对于一个全节点来说,他要维护的状态就太多了,可能要记录隔着一百代以前有哪些区块,你发布的这些区块包含的叔父区块,其他节点同样也是要验证的。

设计是最多隔着七代,并且七代以内出块奖励是递减的,这样有利于鼓励,出现分叉之后,尽早进行合并。

​ 叔父区块的奖励把它叫做uncle reward,他会递减,但是对于包含叔父区块的区块来说,包含一个叔父区块,可以得到1/32的奖励,这个是固定的。

​ 我们设计这个协议,主要是解决系统中临时性的分叉,最长合法链也是为了解决临时性的分叉,合并的机制就是最长合法链会胜出,如果这个分叉是别的原因造成的,比如说,是对运行的区块链协议有不同的意见,那么这种方法是解决不了的,我们讲的这些例子都是state fork:对于区块链当前的状态产生了意见分歧(临时的);如果是别的原因,像我们以前讲的比特币脚本的时候,CHECKMULTISIG的时候,要想堆栈中添加一个多余的元素,应对这个操作会弹出一个无用的元素,为什么不把这个bug改掉?

改完之后,版本不一样了,这样会出现硬分叉,如果分叉的区块认为对方的区块是非法的,那么合并是不可行的。

仍然沿着矿工自己的分叉链去挖。

​ 我们说,比特币发布一个区块,实际上得到的是两种奖励,一部分叫做block reward(静态奖励),一部分叫做tx fee(动态奖励),以太坊中也是类似的,三个以太币是block reward,动态奖励叫做gas fee,在区块里包含了智能合约,执行智能合约的时候可以得到gas fee,我们说的uncle block得到的7/8的奖励,只限于3个以太币(也就是block reward),汽油费是得不到的,但是汽油费是很少一部分的,大部分是block reward。(和比特币类似)

​ 如果以太坊中也变成了block reward趋于0,那么uncle reward不也是趋于0吗?

以太坊中没有规定时间减少block reward的说法。比特币这么规定是因为比特币的稀缺性,以太坊中的5个以太币17年降为3个以太币不是为了人为制造稀缺性,实际上和挖矿难度调整有关的。(17年的事件是一次性的,没有说会一直下调)比特币被别人当成数字黄金,是用来储值的,以太币被别人比喻成石油,是用来花的,并且可以执行智能合约。(但是这里的比喻其实是不恰当的,因为石油用完就没了,但是以太币就是相当于电子现金),发布智能合约要花费gas fee,执行智能合约的那个矿工可以得到gas fee。(以太币和比特币的设计理念是不一样的)

​ 把叔父区块包含进来的时候,叔父区块里的交易要不要执行?

以太坊是一个交易驱动的状态机,比特币也一样,所以每次发布一个新的区块都会使当前状态转化成下一个状态。

不应该执行,最长合法链上的父区块,和uncle block里面的交易可能是重复的,一种想法是相同的交易不执行,不同的交易就执行,但是这种情况下,不同的交易可能不可以一起执行。(可能是有冲突的交易)你要执行叔父区块的交易,可能某些交易就变成了非法交易,叔父区块的交易不一定是非法的,你执行完父区块的交易,再去执行叔父区块的交易,可能就变成非法的了。

​ 以太坊是不执行叔父区块里的交易的,而且是不检查叔父区块的合法性的,主链上的区块知道这个叔父区块的时候,只检查叔父区块是不是一个合法发布的区块,换句话说,这个区块是不是符合挖矿难度,至于这个区块里的交易合不合法不检查,不执行,执行起来的话,可能和主链上的交易是冲突的,叔父区块里的交易不执行,但是主链上的区块收到叔父区块里的交易,这个交易会被放在主链上执行。

​ 怎么检测链上有多少个叔父区块?

听到一个就查一下,每个发布的区块说明它的父区块是哪一个,所以可以检测到你的父区块和当前区块是不是有共同祖先。

​ 上述的例子的叔父区块都是分叉的第一个区块,如果分叉之后,分叉的那个区块后面跟着的那些区块怎么办?

这样的话,可不可以给他们每个分叉都一部分奖励,“招安”的时候相当于是“招安一伙”?免得出现两个分叉的情况

这样改的话,forking attack就变得太便宜了,攻击成了,我把你的交易回滚了,攻击不成,你反正把我“招安”过去,我也能得到一些出块奖励,所以以太坊规定,只有分叉后的第一个区块可以得到uncle reward

叔父区块的不同情况:

Block Height:区块的序号,也就是block number

UncleNumber:叔父区块在区块链中的序号

看uncle number 和block height的差值,判断,相差多少代,上图说明,系统中的大多数区块都及时地得到了合并

叔父区块奖励的具体内容: