区块链规则更新过程

本文翻译于 https://gist.github.com/gavinandresen/2355445,写于 2012 年

作者:GavinAndresen

译者:李康

最近我们对比特币区块接收规则实施了两个改变 (BIP 16 与 BIP 30);该篇文献记录了在规则改变过程中学习到的经验教训,并且对于未来区块链规则改变的处理提出建议。

注意:存在 "soft" 规则与 "hard" 规则的改变。"Soft" 分叉收紧了规则,即旧版本软件将会接受所有由新版本软件创造的区块与交易,但是反之则不一定正确。"Soft" 分叉不需要整个网络的矿工、商家、用户升级软件,他们也不会落后。

"Hard" 分叉修改了规则,以致旧版本的、未升级的软件认为是非法的,即在旧版本软件看来是无效的交易在新版本软件看来可能是有效的。在这点看来,硬分叉是更难实施的,因为硬分叉需要每一个矿工、商家、用户来升级软件。

学习到的经验教训

  • 确保考虑到四种情况:旧/新版本软件运行,在网络中大部分节点支持新规则之前/之后。

  • 向后兼容旧版本矿工/客户端是极其重要的。

  • 在部署改变到主网之前,应先在测试网部署。

  • 考虑奠定一个坚实的基础,然后分阶段实施这些改变。一步一步来而不是一次将这些改变全部实施。

如果我可以再一次实施 BIP 16,并且知道现在我知道的所有事情,我将会分 3 个阶段实施 BIP 16 的改变:

  1. 收紧 "IsStandard" 规则,这样可以检查 "standard" 输入,这么做可以阻止旧版本矿工意外地将 invalid-under-new-rules 交易 (即在旧版本中有效但在新版本中无效的交易)包含进它们的区块中。

  2. 添加 n-of-3 CHECKMULTISIGs 作为 "standard" 交易。

  3. 添加 BIP 16 "pay to script hash" 作为 "standard" 交易。

完全无争议的改变可以在相对很快的时间内完成 (1-2 weeks)。

BIP 30 (用来解决相同交易带来的问题) 是一个完全无争议改变的示例。

  • 有争议的改变或许需要花费数月来部署,即使在拥有了大部分核心开发者、矿工、用户之后。

BIP 16 是一个有争议改变的示例。

  • 人是易出错的,如果你依赖人们设置配置文件来支持新特性,那你就要考虑到错误的发生。

在 BIP 16 采纳期间,一些支持 BIP 16 的矿工没能向从属它们的节点更新 BIP 16 的切换时间,导致在小部分链上浪费了时间去做哈希计算。另外一些用户也同样遭遇了此类问题,因为它们正在使用旧版本软件而没有更新。

它们很快就意识到并且修复了它们的错误,但是如果改变的切换时间是根据区块链的历史自动确定的而不是一个固定的,这种方式将会更好。实现这种方式的代码只需要编写一次并且测试一次,然后就可以在未来的升级中被复用。

  • 区块和交易都有版本号字段,那么使用它们!

在 BIP 12/BIP 16/BIP 17 提案随后的讨论中,一些人建议新交易应该有一个新的版本号。这是一个很好的想法,我们这些核心开发者应该在提案执行的开始就该考虑到的。我们应该使用区块和交易的版本号来支持新格式的交易。

对于矿工来说,区块版本号是一个更好的方法来预示他们正在使用的验证规则,并且来判断对于新的验证规则是否有大部分的支持 (BIP 16 将字符串 "/P2SH" 放入 coinbase 交易来判断支持率)。

如果一个旧版本软件发现区块链中最近一些区块的大部分区块拥有一个它不能理解的版本号应该警告用户软件已经过时,并且需要更新,但是会忽视版本号并且执行正常的区块和交易验证。

交易版本号是一个更好的方法来具体化验证该交易是否有效的规则。在中继交易或将其包含进挖出的区块中之前,旧版本号的交易将会在旧规则下进行验证,新版本号的交易将会在新规则下进行验证。为了避免处于区块链的一个小部分分叉中,出现在区块中的新版本号的交易只有当比特币网络中大部分节点支持这个新特性的时候 (通过最近 N 个区块中的版本号来确定) 才会在新规则下进行验证。

一个交易的版本号是它哈希 (即 Transaction ID) 的一部分,并且是它签名使用的哈希的一部分,所以不能被一个攻击者改变。然而,使用新交易特性的软件需要,在要求用户提供签名或者告诉用户该交易已经被合适地签名之前,确保交易有正确的版本号。

推荐的升级过程

需要对比特币核心进行一些修改来使未来的升级过程更加平滑:

  • 如果一笔交易有着未知的版本号,那么认为该笔交易是非标准的 (不会接受它到内存池中)。

  • 实现代码来跟踪最近 1000 个区块版本号数量的统计。

  • 如果最近 1000 个区块中的 55% 或者更多有一个未知的版本号,警告用户,需要升级比特币软件。

升级场景:

下面是一些未来升级如何以最小风险的方式来处理的概况。

例子:重新定义 OP_NOP1 成为 OP_Q_CHECKSIGVERIFY,使用一种抵抗量子计算的数字签名算法。

  1. 操作码必须被这样设计:要么该交易验证失败,要么它表现地像一个 no-op 操作。任何其它的设计 (例如该操作码消费栈中的元素,或者在栈中留下数据) 将会使攻击者伪造在新规则下有效但在旧规则下无效的交易,导致区块链的分叉。

  2. 使用新操作码的交易被赋予一个新的版本号。

  3. 运行新版本软件的矿工产生有新版本号的区块,那么新特性的支持率可以被测量。

  4. 新节点将 OP_NOP1 解释为 OP_Q_CHECKSIGVERIFY,当且仅当交易的版本号是正确的,并且最近创建的 1000 个区块的 75% 有更新过后的版本号 (测试网上达到 51% 即可)。

注意 "75%" 的规则自动地处理旧的区块链中可能包含 invalid-under-new-rules 交易的部分区块,也处理支持率的波动。区块链中少于 75% 的支持度的部分在旧版本规则下进行验证,超过 75% 的部分在新版本规则下进行验证。用户不应该依赖新特性直到有一个清晰,一致的支持率。

例子:增加 MAX_BLOCK_SIZE (一个区块链的硬分叉)

增加区块的最大容量,超出现在的 1M 限制,(或许将它改变为一个基于过去一些块间的中位容量与相关因数的乘积) ,这是一个极有可能的未来升级以便每个区块能够容纳更多的交易。一个新的最大区块容量规则可能以下列方式实施:

  1. 新版本软件创建有新版本号的区块。

  2. 允许大于 MAX_BLOCK_SIZE 的区块,如果它们的版本号是新版本号或者更高,并且最近 1000 个区块的 100% 是新版本号的区块。(测试网上,是 51%)

最近 1000 个区块的 100% 规则可能比较理想,实际的准则可能稍微有点不同 (可能是区块的时间戳在 2015 年 1 月 1 日之后并且最近 2000 个区块的 99% 是新版本号),既然这个改变意味着第一个有效的大于 MAX_BLOCK_SIZE 的区块立刻将运行旧版本软件的矿工踢出祝区块链。


译者注:

1.BIP 34 是基于该更新规则的软件升级,该提案有两个动机:

  • 行使比特币网络集体同意升级区块、交易二进制结构,规则,行为的机制。

  • 强制区块与交易的唯一性,并且协助未连接的区块验证。

该提案将当前区块高度加入区块的 coinbase 交易中,并且区块的版本号由 1 升级到 2。

该提案与上述更新规则稍微有点不同的是,该提案增加了 95% 规规则 - "Point of no return",即如果最近 1000 个区块中包含超过 95% 的区块有 2 或者更高的版本号,那么拒绝所有版本号为 1 的区块。

BIP 34 中因为没有改变交易验证的规则,所以交易的版本号没有进行升级,因此交易的版本号还是 1。

2.BIP 66 提案使用了版本号为 3 的区块,BIP 65 提案使用了版本号为 4 的区块,但注意,交易的版本号一直是 1 。译者认为后续比特币的软分叉升级只根据了区块的版本号,而没有根据交易的版本号。

3.由于该升级规则的局限性,比特币核心开发者们提出了 BIP 9

results matching ""

    No results matching ""