我们不定期更新我们的开发心得,汇总在 github 上,欢迎 star: https://github.com/rrtoken/DAPP_Blog
是指由矿工节点组成的比特币网络对所有该产生的合法区块进行确认(同时否认不合法区块,丢弃掉)。由于每个区块又包含了若干交易, 所以也就等于对所有交易进行了确认,达到共识。 这里的合法,我认为是合乎比特币设计算法规定,而不是法律意义上的合法。
由于参与比特币挖矿的节点数量巨大,地理上又分布于不同的地方,网络状况也不尽相同。是一个极端分散的分布式系统。每个矿工节点收到网络上广播的用户交易的顺序,数量都不一样。每个矿工看到的都是不同的 view。因此,比特币的共识算法本质上就是要随机选择出一个具体块的矿工。之前在知乎上看到一位大牛的说法,适当的随机数产生算法对公链的设计是最关键的。
选择当前的出块节点必须是随机的。如果某个节点知道某一个高度的块一定产生于自己,那么他就可以没有成本的作弊。为了让那些试图伪造比特币交易(例如 double spend )的人增加成本,比特币选择了一种需要大计算量来产生随机数的方法。这就是工作量证明,PoW。
矿工在把若干交易打包在之后,就需要选择一个随机数 c。这个 c 的值要满足一个条件,就是把 c 和打包好的交易放在一起进行一个 Hash 运算,产生了 Hash 值 h。由于采用了 Hash256,所以运算结果 h 是一个 256bit 的数字。该数字类似于一个随机数,因为你无法根据 c 来大致猜测这个数字在什么范围。 比特币网络有一个难度值 d,该难度值是动态调整的。每个时间段都会进行调整。 如果 h <pow(2, 224) / d。那么就认为 c 是合法的,然后把 c 和交易一起打包在一个区块中并广播出去。 由于我们无法根据 c 的值来得知 h 的范围。所以只有枚举所有 c 的值进行 SHA256 的计算。如果 d 的值越大,h 值的合法区间就越小,那么尽快找到 c 的概率就越低。如果系统算力增加,那么通过调 整 d 的值就可以调整 c 被发现的概率速度。
为了保证交易的顺序性,每个区块里面还要记录上一个区块的 hash,也就是对父亲区块的引用。从而形成一条 chain。但是由于系统的分布性,在同一个时段内,很有可能系统的多个矿工节点都产生了的区块并且被广播出来。这些区块都有相同的父亲。这些分叉就形成了一个树。后面随后产生的 block 有可能又引用这些分叉上的任一个区块作为父亲,那么这个树就越来越大,越来越长。
由于交易的顺序性,我们不可能选择多个分叉记录在案,所以只能选择一条分叉。其余的就会被丢弃。比特币网络的选择就是最长的一条分叉。根据概率,在大致相同的时间段内形成一个同样高度的 3 层树的概率比两层树低很多,更多层的树如果有相同高度的两个分叉的概率就更低。 所以一般认为,如果到六个区块产生之后,就可以有一个最长的分叉宣布胜出了。(大概需要 1 个小时)
由于比特币的完全分布化。整个系统的节点数量处于不断变化中。有些网络会不时的断掉。 考虑一个极端情况,假定由于某种原因(比如防火墙),整个世界的网络在两个小时内分为两个区域。每个区域都会产生自己的最长分叉。当网络情况好转,两个区域合并的时候,必然有一个分叉会被丢弃。 似乎,在一个完全分布化,又不停的有节点加入退出的网络是没有 100%的确认的?只有无限接近 100%。
根据上面的分析,具有 51%算力的人,更大的概率可以在同一时间让自己提交的分叉高度比较其他节点产生的分叉高一点。那么就可以用自己长的分叉来替代别人以为被确认的短分叉。
BFT 的一致性更好,而且,理论上可以达到 100%确认。因为系统中的出块节点个数是预知的,得到 2/3 节点确认就可以完全确认了。 我的理解是,BFT 的出块节点是互相全联通的。而且是互相知晓的。要加入出块,是需要 permission 的。速度会很快,但是如果出块节点增多的话,根据全联通图的特点,其通信开销呈指数增加,很快就受不了了。
1
tutustream 2018-07-02 13:50:43 +08:00
一半以上的算力都直接或者间接握在比特大陆手里吧
|