打造公链智能合约

硬分叉和软分叉

2018-06-29  本文已影响0人  建怀

在讨论硬分叉和软分叉之前,我们先了解下区块链是如何组装和选择成为一条包含最多区块的主链的。

区块链的组装与选择

比特币去中心化的共识机制的最后一步是将区块集合至有最大工作量证明的链中。一旦一个节点验证了一个新的区块, 它将尝试将新的区块连接到到现存的区块链,将它们组装起来。

节点维护三种区块:第一种是连接到主链上的,第二种是从主链上产生分支的(备用链),最后一种是在已知链中没有 找到已知父区块的。在验证过程中,一旦发现有不符合标准的地方,验证就会失败,这样区块会被节点拒绝,所以也不 会加入到任何一条链中。

节点接收到新区块的时候,有三种情况:

选择了最大难度的区块链后,所有的节点最终在全网范围内达成共识。随着更多的工作量证明被添加到链中,链的暂时 性差异最终会得到解决。挖矿节点通过“投票”来选择它们想要延长的区块链,当它们挖出一个新块并且延长了一个链, 新块本身就代表它们的投票。

区块链分叉

每个节点都有自己的全局区块链视图。 当每个节点从其邻居接收区块时,它会更新其自己的区块链副本,选择最大累积工作链。 为便于描述,每个节点包含一个图形形状,表示它相信的区块处于主链的顶端。 因此,如果在节点里面看到星形,那就意味着该节点认为星形区块处于主链的顶端。

网络有一个统一的区块链视角,以星形区块为主链的顶点。


image

当有两个候选区块同时想要延长最长区块链时,分叉事件就会发生。两个矿工在各自的候选区块一发现解,便立即传播自己的“获胜”区块到网络 中,先是传播给邻近的节点而后传播到整个网络。每个收到有效区块的节点都会将其并入并延长区块链。如果该节点在 随后又收到了另一个候选区块,而这个区块又拥有同样父区块,那么节点会将这个区块连接到候选链上。其结果是,一 些节点收到了一个候选区块,而另一些节点收到了另一个候选区块,这时两个不同版本的区块链就出现了。

image

假设矿工节点X找到扩展区块链工作量证明的解,即三角形区块,构建在星形父区块的顶端。与此同时,同样进行星形区块扩展的节点Y也找到了扩展区块链工作量证明的解,即倒三角形区块作为候选区块。现在有两个可能的块,节点X的三角形区块和节点Y的倒三角形区块,这两个区块都是有效的,均包含有效的工作量证明解并延长同一 个父区块。这个两个区块可能包含了几乎相同的交易,只是在交易的排序上有些许不同。

​当两个区块开始在网络传播时,一些节点首先接收到三角形区块,另外一些节点首先接收倒三角形区块。如下图所示,比特币网络上的节点对于区块链的顶点产生了分歧,一派以三角形区块为顶点,而另一派以倒三角形区块为顶点。

image

​双方都是“正确的”或“不正确的”。两者都是自己关于区块链的有效立场。只有事后,才能理解这两个竞争链如何通过额外的工作得到延伸。

节点X阵营的其他节点将立即开始挖掘候选区块,以“三角形”作为扩展区块链的顶端。通过将三角形作为候选区块的父区块,它们用自己的哈希算力进行投票。它们的投票标明支持自己选择的链为主链。

同样,节点Y阵营的其他节点,将开始构建一个以倒三角形作为其父节点的候选节点,扩展它们认为是主链的链。比赛再次开始。分叉问题几乎总是在一个区块内就被解决了。网络中的一部分算力专注于“三角形”区块为父区块,在其之上建立新的区 块;另一部分算力则专注在“倒三角形”区块上。即便算力在这两个阵营中平均分配,也总有一个阵营抢在另一个阵营前发现工作量证明解并将其传播出去。在这个例子中我们可以打个比方,假如工作在“三角形”区块上的矿工找到了一个“菱形”区块 延长了区块链(星形-三角形-菱形),他们会立刻传播这个新区块,整个网络会都会认为这个区块是有效的,如下图所示。

image

选择“三角形”作为上一轮中胜出者的所有节点将简单地将区块链扩展一个块。然而,选择“倒三角”的节点现在将看到两个链:星形-三角形-菱形和星型-到三角形。星形-三角形-菱形这条链现在比其他链条更长(更多累积的工作)。因此,这些节点将星形-三角形-菱形设置为主链,并将星型-倒三角形链变为备用链,如下图所示。这是一个链的重新共识,因为这些节点被迫修改他们对块链的立场,把自己纳入更长的链。

image

单区块分叉每周都会发生,而双块分叉则非常罕见。比特币将区块间隔设计为10分钟,是在更快速的交易确认和更低的分叉概率间作出的妥协。更短的区块产生间隔会让交 易清算更快地完成,也会导致更加频繁地区块链分叉。与之相对地,更长的间隔会减少分叉数量,却会导致更长的清算时间。

共识攻击

比特币的共识机制指的是,被矿工(或矿池)试图使用自己的算力实行欺骗或破坏的难度很大,至少理论上是这样。就像我们前面讲的,比特币的共识机制依赖于这样一个前提,那就是绝大多数的矿工,出于自己利益最大化的考虑,都会 通过诚实地挖矿来维持整个比特币系统。然而,当一个或者一群拥有了整个系统中大量算力的矿工出现之后,他们就可 以通过攻击比特币的共识机制来达到破坏比特币网络的安全性和可靠性的目的。

值得注意的是,共识攻击只能影响整个区块链未来的共识,或者说,最多能影响不久的过去几个区块的共识(最多影响 过去10个块)。而且随着时间的推移,整个比特币块链被篡改的可能性越来越低。

共识攻击也 不能从其他的钱包那里偷到比特币、不签名地支付比特币、重新分配比特币、改变过去的交易或者改变比特币持有纪 录。共识攻击能够造成的唯一影响是影响最近的区块(最多10个)并且通过拒绝服务来影响未来区块的生成。共识攻击的一个典型场景就是“51%攻击”。想象这么一个场景,一群矿工控制了整个比特币网络51%的算力,他们联合 起来打算攻击整个比特币系统。由于这群矿工可以生成绝大多数的块,他们就可以通过故意制造块链分叉来实现“双重支 付”或者通过拒绝服务的方式来阻止特定的交易或者攻击特定的钱包地址。

区块链分叉/双重支付攻击指的是攻击者通过 不承认最近的某个交易,并在这个交易之前重构新的块,从而生成新的分叉,继而实现双重支付。有了充足算力的保 证,一个攻击者可以一次性篡改最近的6个或者更多的区块,从而使得这些区块包含的本应无法篡改的交易消失。值得注意的是,双重支付只能在攻击者拥有的钱包所发生的交易上进行,因为只有钱包的拥有者才能生成一个合法的签名用 于双重支付交易。攻击者在自己的交易上进行双重支付攻击,如果可以通过使交易无效而实现对于不可逆转的购买行为不予付款, 这种攻击就是有利可图的。

为了避免这类攻击,售卖大宗商品的商家应该在交易得到全网的6个确认之后再交付商品。或者,商家应该使用第三方 的多方签名的账户进行交易,并且也要等到交易账户获得全网多个确认之后再交付商品。一条交易的确认数越多,越难 被攻击者通过51%攻击篡改。需要注意的是,51%攻击并不是像它的命名里说的那样,攻击者需要至少51%的算力才能发起,实际上,即使其拥有不 到51%的系统算力,依然可以尝试发起这种攻击。之所以命名为51%攻击,只是因为在攻击者的算力达到51%这个阈值 的时候,其发起的攻击尝试几乎肯定会成功。

本质上来看,共识攻击,就像是系统中所有矿工的算力被分成了两组,一 组为诚实算力,一组为攻击者算力,两组人都在争先恐后地计算块链上的新块,只是攻击者算力算出来的是精心构造 的、包含或者剔除了某些交易的块。因此,攻击者拥有的算力越少,在这场决逐中获胜的可能性就越小。

从另一个角度 讲,一个攻击者拥有的算力越多,其故意创造的分叉块链就可能越长,可能被篡改的最近的块或者或者受其控制的未来 的块就会越多。一些安全研究组织利用统计模型得出的结论是,算力达到全网的30%就足以发动51%攻击了。全网算力的急剧增长已经使得比特币系统不再可能被某一个矿工攻击,因为一个矿工已经不可能占据全网哪怕的1%算 力。

但是中心化控制的矿池则引入了矿池操作者出于利益而施行攻击的风险。矿池操作者控制了候选块的生成,同时也控制哪些交易会被放到新生成的块中。这样一来,矿池操作者就拥有了剔除特定交易或者双重支付的权力。如果这种权利被矿池操作者以微妙而有节制的方式滥用的话,那么矿池操作者就可以在不为人知的情况下发动共识攻击并获益。但是,并不是所有的攻击者都是为了利益。

一个可能的场景就是,攻击者仅仅是为了破坏整个比特币系统而发动攻击, 而不是为了利益。这种意在破坏比特币系统的攻击者需要巨大的投入和精心的计划,因此可以想象,这种攻击很有可能 来自政府资助的组织。同样的,这类攻击者或许也会购买矿机,运营矿池,通过滥用矿池操作者的上述权力来施行拒绝 服务等共识攻击。但是,随着比特币网络的算力呈几何级数快速增长,上述这些理论上可行的攻击场景,实际操作起来 已经越来越困难。

近期比特币系统的一些升级,比如旨在进一步将挖矿控制去中心化的P2Pool挖矿协议,也都正在让这 些理论上可行的攻击变得越来越困难。毫无疑问,一次严重的共识攻击事件势必会降低人们对比特币系统的信心,进而可能导致比特币价格的跳水。然而,比 特币系统和相关软件也一直在持续改进,所以比特币社区也势必会对任何一次共识攻击快速做出响应,以使整个比特币 系统比以往更加稳健和可靠。

改变共识规则

共识规则确定交易和块的有效性。 这些规则是所有比特币节点之间协作的基础,并且负责将所有不同角色的本地视角融合到整个网络中的单一一致的区块链中。虽然共识规则在短期内是不变的,并且在所有节点之间必须一致,但长期来看它们并不总是不变的。 为了演进和开发比特币系统,规则必须随时改变以适应新功能,改进或修复错误。 然而,与传统软件开发不同,升级到共识系统要困难得多,需要所有参与者之间的协调。

硬分叉

研究了比特币网络如何短暂地分叉,网络中的两个部分在短时间内处于区块链的两个不同分支。我们看到这个过程是如何自然发生的,作为网络的正常运行的一部分,以及如何在一个或多个块被挖掘之后,网络在一个统一的区块链上重新收敛。

另一种情况是,网络也可能会分叉到两条链条,这是由于共识规则的变化。这种分叉称为硬分叉,因为这种分叉后,网络不会重新收敛到单个链路上。相反,这两条链子独立发展。当比特币网络的一部分节点按照与网络的其余部分节点不同的一致性规则运行时,硬分叉就会发生。

这可能是由于错误或者由于故意改变了协商一致规则的实施而发生的。硬分叉可用于改变共识的规则,但需要在系统中所有参与者之间进行协调。没有升级到新的共识规则的任何节点都不能参与共识机制,并且在硬分叉时刻被强制到单独的链上。

因此,硬分叉引入的变化可以被认为不是“向前兼容”,因为未升级的系统不能再处理新的共识规则。让我们来看一下硬分叉的技巧和具体的例子。下图显示区块链出现两个分叉。在块高度4处,发生单一个区块分叉。这是我们在前面章节比特币分叉中看到的自发分叉的类型。经过块5的挖掘,网络在一条链上重新收敛,分叉被解决。

image

然而,后来在块高度6处发生了硬分叉。我们假设原因是由于新共识规则的变化出现新的客户端版本。从块高度7开始,矿工运行新的版本,需要接受新类型的数字签名,我们称之为“Smores”签名,它不是基于ECDSA的签名。紧接着,运行新版本的节点创建了一笔包含Smores签名的交易,一个更新了软件的矿工挖矿出了包含此交易的区块7b。
这两个链条从这一点继续分歧。 “b”链的矿工将继续接受并开采含有Smores签名的交易,而“a”链上的矿工将继续忽视这些交易。即使块8b不包含任何Smores签名的交易,“a”链上的矿工也无法处理。对他们来说,它似乎是一个孤立的块,因为它的父“7b”不被识别为一个有效的块。

硬分叉:软件,网络,采矿和链

当一组开发人员选择遵循不同的软件路线图并启动开源项目的竞争实施时,会发生叉。我们已经讨论了两种情况,这将导致硬分叉:共识规则中的错误,以及对共识规则的故意修改。对于这种类型的硬分叉,新的共识规则必须通过开发,采用和启动新的软件实现。

试图改变共识规则的软分叉的例子包括Bitcoin XT,Bitcoin Classic和最近的Bitcoin Unlimited。但是,这些软分叉都没有产生硬分叉。虽然软件叉是一个必要的前提条件,但它本身不足以发生硬分叉。对于硬分叉发生,必须是由于采取相互竞争的实施方案,并且规则需要由矿工,钱包和中间节点激活。相反,有许多比特币核心的替代实现方案,甚至还有软分叉,这些没有改变共识规则,阻止发生错误,可以在网络上共存并互操作,最终并未导致硬分叉。

将硬分叉子看成四个阶段:软分叉,网络分叉,挖矿分叉和区块链分叉。该过程开始于开发人员创建的客户端,这个客户端对共识规则进行了修改。当这种新版本的客户端部署在网络中时,一定百分比的矿工,钱包用户和中间节点可以采用并运行该版本客户端。得到的分叉将取决于新的共识规则是否适用于区块,交易或系统其他方面。如果新的共识规则与交易有关,那么当交易被挖掘成一个块时,根据新规则创建交易的钱包可能会产生出一个网络分叉,这就是一个硬分叉。如果新规则与区块有关,那么当一个块根据新规则被挖掘时,硬分叉进程将开始。

首先,是网络分叉。基于旧的共识规则的节点将拒绝根据新规则创建的任何交易和块。此外,遵循旧的共识规则的节点将暂时禁止和断开发送这些无效交易和块的任何节点。因此,网络将分为两部分:旧节点将只保留连接到旧节点,新节点只能连接到新节点。基于新规则的单个交易或块将通过网络波动,实现分区,导致出现两个网络。

一旦使用新规则的矿工开采了一个块,挖矿和区块链也将分叉。新的矿工将在新区块之上挖掘,而老矿工将根据旧的规则挖掘一个单独的链条。处于分区的网络将使得按照各自共识规则运行的矿工将不会接收彼此的块,因为它们连接到两个单独的网络。

分离矿工和难度

随着矿工们被分裂开始开采两条不同的链条,链上的哈希算力也被分裂。两个链之间的挖矿能力可以分成任意比例。新的规则可能只有少数人跟随,或者也可能是绝大多数矿工。

软分叉

并非所有共识规则的变化都会导致硬分叉。只有前向不兼容的共识规则的变化才会导致分叉。如果共识规则的改变也能够让未修改的客户端仍然按照先前的规则对待交易或者区块,那么就可以在不进行分叉的情况下实现共识修改。这就是软分叉,来区分之前的硬分叉。实际上软分叉不是分叉。软分叉是与共识规则的前向兼容并作些变化,允许未升级的客户端程序继续与新规则同时工作。

软分叉的一个不是很明显的方面就是,软分叉级只能用于增加共识规则约束,而不是扩展它们。为了向前兼容,根据新规则创建的交易和块也必须在旧规则下有效,但是反之亦然。新规则只能增加限制,否则,根据旧规则创建的交易和区块被拒绝时,还是会将触发硬分叉。

软叉可以通过多种方式实现,该术语不定义单一方法,而是一组方法,它们都有一个共同点:它们不要求所有节点升级或强制非升级节点必须脱离共识。

使用区块版本发出软分叉信号

由于软分叉允许未经修改的客户在协商一致的情况下继续运作,“激活”软分叉的机制是通过向矿工发出信号准备:大多数矿工必须同意他们准备并愿意执行新的共识规则。 为了协调他们的行动,有一个信号机制,使他们能够表达他们对共识规则改变的支持。 该机制是在2013年3月激活BIP-34并在2016年7月被BIP-9激活所取代。

BIP-9信号和激活

BIP-9将块版本解释为bit字段而不是整形(int)字段。因为块版本最初作为整形(int32)字段,因此版本1到4,只有29位可用作bit字段。这留下29位,可以独立使用,同时在29个不同的提案上表示准备就绪。BIP-9还设置了信令和激活的最大时间。矿工们不需要永远发出信号。如果提案在TIMEOUT期间(在提案中定义)未激活,则该提案被视为被拒绝。该提议可以使用不同位的信令重新提交,更新激活周期。

此外,在TIMEOUT已经过去并且特征被激活或被拒绝之后,信令位可以被再次用于另一个特征而不会混淆。因此,多达29次更改可以并行发出信号,TIMEOUT后可将这些位“再循环”以提出新的更改。

注意虽然信令位可以重复使用或回收利用,但只要投票期间不重叠,BIP-9的作者就建议仅在必要时重复使用位; 主要是由于旧软件中的bug,可能会发生意外的行为。 总之,我们不应该期望在所有29位都被使用一次之前看到重用。

建议的更改由包含以下字段的数据结构标识:名称用于区分提案的简短描述。 通常,BIP将该提案描述为“bipN”,其中N是BIP编号。位0到28,矿工使用的块版本中的位用于表示此提案的批准。开始时间信号开始的时间(基于中值时间过去或MTP),之后该位的值被解释为提示的信令准备。时间结束该时间(基于MTP),如果尚未达到激活阈值,则认为该更改被拒绝。

与BIP-34不同,BIP-9根据2016块的难度改变目标(retarget)周期,在整个间隔周期中计算激活信号的数量。 在每个难度调整周期内,如果提案的激活信号数量总和超过95%(2016中的1916),则该提案将在下一个难度调整周期内激活。BIP-9提供了一个提案状态图,以说明一个提案的各个阶段和转换,如下图所示。

image

一旦它们的参数在比特币软件中被知道(定义),提案将在DEFINED状态下开始。 对于具有MTP的块在开始时间之后,提议状态转换到STARTED。 如果在改变目标期间超过了投票阈值,并且未超过超时,则提案状态转换为LOCKED_IN。 一个改变目标期后,该提案变为活动。

一旦达到这个状态,提案仍然处于活动状态。 如果在达到投票阈值之前超时时间,提案状态将更改为“已故”,表示已拒绝的提案。 REJECTED的建议永远在这个状态。BIP-9首次实施用于激活CHECKSEQUENCEVERIFY和相关BIP(68,112,113)。 名为“csv”的建议在2016年7月成功启动。标准定义在BIP-9(Version bits with timeout and delay).

上一篇下一篇

猜你喜欢

热点阅读