中本聪创建的原始比特币客户端(0.1.0 版本),其脚本引擎与我们今天的脚本引擎存在显著差异。最初的脚本支持任意大小的整数进行数学运算(密码学),其大小等方面也没有限制。此后,在比特币发展的某一时间点,才开始实施每脚本 201 个操作码的限制。
比特币是用一种丰富的脚本语言创建的。如果它的用途仅限于两个私钥之间的直接支付,就算包括多重签名交易,那也根本不需要脚本语言。这些功能完全可以简单地通过硬编码实现,代码还能大大地简化了。但比特币是建立在一种具有丰富指令集的脚本语言之上的,这表明它始终是一个用更复杂的规则集去管理资金转移的基础平台。将比特币恢复到最初的预定设计(当然我们也要修复其中的bug)本身就是一个原因。
8年过去了,现在人们对这些操作码的边界例子有了更好的理解。8年也给了人们很多时间来思考如何使用这些操作码。此外,它们当初是在仓促的情况下被迫禁用的。BSV 社区现在已经有了充裕的时间来彻底解决这些问题。
比特币 SV 执行团队建议去除或者提高每个脚本 201 个操作码的上限,引发了人们对黑客攻击的担忧,此类攻击将引起网络超载。
在这篇文章中,我将量化风险并解释相应的缓解措施,通过这些措施,我们将极有可能在不颠覆传统的情况下完成这项工作。
撇开大脚本可能存在的问题,例如展开的循环和复杂的算法结构等,我先来探讨几个问题。
比特币 SV 的愿景是恢复原始比特币协议并将其锁定(安全修复及为满足扩展目标所必需的更改情况除外)。在我们看来,“协议”通常由以下几点构成:
- 白皮书
- 原始代码
- 中本聪通过修复漏洞设置的明显例子
- 他此后对协议的一些思考
我个人相信这个目标的原因(非技术论证)或许是:中本聪还未隐退前,比特币尚处于起步阶段。这个系统依赖于用户规模,当用户数量达到一定规模时,系统的许多属性才开始可以实现。即使中本聪在的时候,也已经开始施加限制(虽然后来用户达到一定规模后,他曾表示要去除限制),并且这种趋势在他离开后仍在继续,比特币出现了越来越多的分叉,和最初的版本越来越不同。这种现象在费用替代方案 (Replace By Fee, 简称 RBF) 和隔离见证 (SegWit) 出现时达到了巅峰。而这也是压死骆驼的最后一根稻草,并最终使比特币以比特币现金的形式重生。
如今比特币 Core �开发组终于摆脱了链上扩容派的枷锁,我们也将有望迎来关键时刻。这也是史上第一次,比特币终于有望实现其最初的目标。问题是,我们尚不知道目标是什么。比特币是基于博弈论、经济激励、密码学等之间复杂作用的系统。我们知道中本聪认为我们不需要设定任何人为限制,他计划的核心是给矿工提供极富吸引力、以利润为基础的激励措施来解决这个问题。考虑到当下比特币对世界产生的影响及其所代表的巨大变革潜力,我个人认为将协议恢复到它应有的方式并让它沉淀几年是值得的 – 让比特币成为它至今还未有机会成为的样子。只有这样,我们才有机会看到比特币所代表的技术和社会学相互作用的结果以及其可借鉴的东西。这是我们欠中本聪的。
比特币脚本的存在以及它最初没有设限的事实,强有力地说明了中本聪设想这种语言的使用方式是我们尚未构想到的。
现在我们重新回到有趣的技术细节上。
在当前的应用中,实际上的确有一些限制与脚本大小相关:
- 每个脚本 201 个操作码
- 每个脚本 10000 字节
- 每笔交易 20000 签名操作(sigops)
- 每 MB 20000 签名操作(但 3 和 4 普遍被认为完全破坏了技术应用)
- 每笔交易 1MB
第 2 点非常重要,因为人们通常有一个误解,即解除每个脚本 201 个操作码的限制等同于每个脚本大小不受限制。 实际并非如此,因为 10000 字节的限制仍发挥作用。 另外需要注意的是,此限制同时将操作码和数据计算在内。
限制脚本大小的另一重要因素,一开始就已构建到比特币中:即交易费用。
就提高每个脚本操作码上限而言,人们通常担忧的问题是计算成本。 运行 201 个操作代码的脚本所耗费的算力不是比运行 10000 个操作代码的脚本少的多吗?答案是肯定的,前者消耗的算力必然要少(虽然我们即将看到的只是轻微差别),但对矿工而言,前者相对更有利可图。 从矿工的角度来看,100 次每次 10 satoshis 和 10 次每次 100satoshis 的收益相当。(注:
这个观点很简单,因为它没有考虑不同操作码间计算成本的差异。但这是一个很好的开始,让我们来看下这种差异会带来怎样的改变。
请注意上述提到的限制之一是每兆字节签名操作的最大值。 签名操作是 OP_CHECKSIG 和 OP_CHECKMULTISIG 操作码(及其验证变体)调用的 ECDSA 签名验证操作的通用术语。 与其他操作码相比,这些操作码的处理成本要比前者高出几个数量级。 直到最近,大多数客户端仍采用单线程处理。
那么攻击者是如何利用这一情况,来攻击比特币呢? 在衡量一个变更的潜在影响时,仅比较正常使用场景和变更后攻击场景的影响是不够的。将变更前的攻击场景与变更后的攻击场景进行比较,可以获取更多信息。
增加签名操作 只为乐趣不为利益
为了分析不同的攻击场景,我将使用一个称为 sigop(签名操作)密度的度量概念,可以衡量你能打包到固定字节数的签名操作数量。在当前费用模型下,因为固定字节数与交易费用成比例,所以这个方式很有用。 因此,它实际上是衡量算力负荷的交易费用的一个指标。
因为签名操作目前算力成本非常高,所以创建一个包含尽可能多的签名操作的区块,使矿工花费很长时间来验证一个区块的方法是可行的。此外,可行的另一部分原因是因为比特币客户端软件中的签名验证代码效率低。发起此攻击需要尽可能增加块的签名操作数量,也就意味着用许多非标准交易来代替标准交易。因此除非有矿工愿意接受任何类型的交易,否则攻击者可能不得不自己挖矿。
最严重的攻击——10 年来从未有人发起
接下来我将提出一些简化此检测的假设。这些假设对最终结果的影响很小,但没有这些假设前提,问题解释就会变得很复杂:
- 我将假设我们只讨论一个脚本而不是两个单独的脚本(scriptSig 和 scriptPubKey)
- 在计算数据大小时,我将忽略交易的其余部分,并且只考虑脚本本身的字节(这样做实际上会使数字结果看起来稍微差一点,所以这是对我目前项目的偏见)
调用一个 sigop 需要 3 个操作码和脚本中大约 107 个字节,并把两个数据(签名和公钥)和 OP_CHECKSIG 本身一起压栈。
<sig> = 1 + 71 字节 (平均)
<pubkey> = 1 + 33 字节
CHECKSIG = 1 字节
总计 = 107 字节 (平均)
有几种方法可以实现更高的签名操作密度。
-
只压栈一个签名和公钥,然后使用 OP_DUP2 为每个新签名操作重新复制。 然而,如果使用签名缓存,这个方法就很容易失效,其降低了每个签名操作缓存查找的成本。
-
压栈多个签名但重用相同的公钥。 这一操作需要 5 个操作码而非原先的 3 个,但节省了大约 32 个字节。 脚本如下:<sig> <pk> DUP TOALTSTACK CHECKSIG <sig> FROMALTSTACK DUP TOALTSTACK CHECKSIG …
当存在 201 个操作码的限制情况时,仅仅反复重复 <sig> <pubkey> CHECKSIG 不能实现更大的签名操作密度。
在达到上限之前,大约可以加入 67 个签名操作,消耗大约 7169 个字节。
每个脚本设有 201 个操作码限制,我们现在可以自由地使用第二种替代方法,因为我们不需要再担心操作码数量过多,只需担心字节数。
在这种情况下,每个操作大约使用 76 字节。在相同的 7169 字节中,你可以容纳 94 个签名操作。 这相当于最大的签名操作密度增加到(94/67 – 1)* 100%= 40%
有趣的是,删除 10000 字节限制对此签名操作密度几乎没有影响。只需要额外的 34 个字节就可以设置,这将使这次攻击的效率降低 1%。
总而言之,在构建和挖掘完整攻击区块的最严重的情况下,我们的计算成本比之前的最大值高了 40%。这是不容小觑的事情,但对一个应能抗御峰值负荷的系统来说,这也不是世界末日。
如果比特币的整个生命周期中,特别是在比特币现金面对大量反对者的一年里,都没有发生这种攻击,我们是否仍有必要担心这个问题,对此我们是存疑的。但是,我们需要为此做好准备,了解将产生的影响,以及可以缓解这种情况的措施。
第一点显而易见:了解最高容量。正如我之前有关区块大小的文章中所解释的那样,比特币 SV 正在启动我们自己的 Gigablock Testnet 版本(实际上不止一个),我们将对这些客户端(和其他客户端)进行压力测试。其中将包括模拟此攻击,并且攻击脚本的工作已在进行中。我们将为矿工提供容量信息,也将为我们的发展重点提供信息。此变化的影响可能仅限于将块验证时间延长最多 40%,并且仅限于完整(昂贵)攻击情形。
如果结果显示提高每个脚本的操作码上限可能会导致攻击的发生,那么我们当然会重新审视这个问题。对矿工来说,目前已经存在一种缓解此情况的简单工具,即选择块大小的硬上限,从而产生可接受的验证时间。
另一个防御性措施是并行块验证(因此如若有黑客闯入,你可以切换到更容易验证的块)- 我们将根据矿工对该功能的需求优先考虑。
真正的缓解措施是提高签名验证的速度,这是我们路线图的首要任务之一。
如果比特币容量不断增加,我们只能接受其网络、存储和计算基础设施的负载量不断加大,别无他选。我们面对的挑战不是避免负载量的增加,而是应采用专业的企业方法进行容量管理和测试,以便网络安全运行。这是委托 SV 项目的矿工们希望实现的,也正是我们承诺要做的。额外的签名操作负载是交易量增长的自然结果,随着效率的提高就能见到问题解决的成效。这些也是比特币 SV 团队早期将关注的短期实现目标。在我之前的帖子中,我提到了与加速签名验证直接相关的路线图中的几个项目,但效率增益存在自然限制,之后我们必须转向水平扩展策略。
最后,要指出的是这些限制不是由 SV 团队决定,而是由矿工选择的,他们使用其知识和准确的运行指标来为他们的决策提供信息。我们的工作是提供这些指标并改进矿工使用的工具,以发挥他们优化采矿过程的能力。