软分叉激活
指的是一个比特币全节点开始增设一个或多个共识规则的瞬间。这种转换会在节点之间产生协调风险。所以开发者多年来花了相当多的力气来创建和提升软分叉激活机制,以尽可能降低出问题的概率。
软分叉使得网络整体上可以切换到使用新的共识规则,即使不是每个节点都接受这些规则。不过,每当不同的节点使用不同的共识规则,就有某个区块被一些接受但被另一些节点拒绝的风险(它违反了非统一的规则),导致共识错误(链分裂),最终可能出现资金的多重支付以及比特币系统安全性信誉的损失。这是激活机制尝试缓解的主要问题。
历史
新的软分叉激活提议通常被设计成避免之前的软分叉已经遭遇的问题,所以本节尝试概述之前比较著名的软分叉激活尝试。
[2009] 硬编码高度:共识层 nLockTime 启用
这个
已知最早
的软分叉在 Bitcoin 软件 0.1.6 版本中实现(发布于 2009 年 11 月),硬编码在区块高度 31000 处激活,实际发生时间是 2009 年 11 月 22 日。在大部分开发工作都是由中本聪完成时,这种硬编码激活高度的方法至少还用在了
另一个
早期的软分叉中。
[2011] 硬编码时间和手动干预:BIP12
OP_EVAL
失败
在中本聪离开比特币之后,合并到比特币的第一个软分叉代码是
BIP12
OP_EVAL
。本来计划是使用一个
硬编码时间
和在支持变更的算力占比少于 50% 时手动干预的方法。引自 BIP12:
[...] 新的客户端和矿工将解释 OP_EVAL 为一个 no-op,直至 2012 年 2 月 1 日。在此之前,支持的矿工可以将 “OP_EVAL” 字样写在自己生产的区块里面,方便我们计算支持的算力占比。如果在 2012 年1 月 15 日之前没有超过 50% 的算力支持这一变更,激活将会推迟,直到有超过 50% 的算力支持 OP_EVAL(如果显然大部分算力都不会激活这一升级,则升级会被取消)。
手动干预可能是有必要的,因为
OP_EVAL
在激活代码合并之后、推出之前,被发现有一个
严重的漏洞
。虽然这个 bug 被
修复
了,一些开发者担心这个强大的新操作码可能会有其它问题,所以人们就放弃了这次软分叉。
[2012] 再次尝试硬编码时间以及手动干预:BIP16 P2SH
人们提出了多个替代
OP_EVAL
的简化提案(见 BIP
13
/
16
、
17
、
18
和
19
,还有
其它想法
)。而 BIP13/16 支付给脚本哈希值(P2SH)
获得了大部分开发者的支持
。P2SH
使用
了 跟 OP_EVAL 一样的激活机制。最初计划的激活时间是 2012 年 3 月 1 日,但到了 2 月 15 开票日,在最后 100 个区块中,只有不到 50% 的矿工表示他们会在 3 月之前执行 BIP16 规则。这
导致
了一个 “相当长的替代链”(链分裂),因为一些仍然在 3 月 1 日实行 BIP16 的 矿工拒绝了来自多数矿工(不实行新规则)的区块。第二次开票日是在几千个区块之后,3 月 15 日;这一次它获得了足够多的支持。所以开发者在 3 月 30 放出了
Bitcoin 0.6.0
,将激活时间设在了 4 月 1 日。
[2012] 硬编码时间:BIP30 拒绝复制 txid
P2SH 的激活完成后,人们发现可能出现多个交易共用同一个 txid 的情况。就其自身而言,这个 bug 只会导致尝试利用这个 bug 的用户的资金被销毁,但它也可以结合比特币的默克尔树构建中的一些奇怪的行为打破节点间的共识(见
CVE-2012-2459
)。第一个修复这个漏洞的软分叉是 BIP30,它简单将使用同一个 txid 的后发交易标记为无效交易,如果前发交易还有没花费的输出的话。这个修复在开发团队中没有争议,因此在包含 P2SH 激活参数的
Bitcoin 0.6.0
中以硬编码时间的方式
激活
。
[2012] IsSuperMajority (ISM):BIP34 coinbase 前缀
虽然 BIP30 修复了 txid 重合导致的短期问题,比特币开发者知道这只是权宜之计,软件没理由每次收到一笔新交易都要搜索带有未花费输出的所有交易的索引。所以第二个解决方案开始提上日程,旨在消除让 txid 复制变成实用攻击向量的弱点。这就是
BIP34
。对这一次更新,开发者使用了 类似于 BIP16 P2SH 的矿工投票方法,但这一次,准备好支持 EIP34 的矿工需要增加他们的区块的
nVersion
的数值。更重要的是,开发者自动化了比特币代码中新规则的实行,因此他们可以在等待矿工升级期间发布支持软分叉的软件。这个来自 BIP34 的规则用一个叫做
IsSUperMajority()
的函数实现了。最开始它包含了一个
单项的激活阈值
,达到了便开始实行 BIP34 的新共识规则:
75% 规则:如果最新的 1000 个区块中有 75% 是 vision2 或者更大的,就开始拒绝无效的 vision 2 区块
在这个功能的开发期间,人们
决定