BIP30 重复交易规则:两块链上'违章'建筑为何被永久豁免 图 1
BIP30 重复交易规则:两块链上'违章'建筑为何被永久豁免 · 图 1

一个曾经成立的攻击

早期实现默认”交易 ID 全链唯一”。但出块交易(coinbase)的解锁字段可以随意填写,两个不同矿工在两个不同高度凑出相同交易 ID,并非天方夜谭。危险在于:如果更早那个 coinbase 还有未花掉的输出,而后到的重复 ID 交易把它”覆盖”,重新组织区块时资金状态就会错乱。2012 年有人公开发表并演示了利用重复交易把已确认付款打回单重确认、甚至让网络按规则分歧分裂的攻击(对应 CVE-2012-1909),比特币被迫用一次软分叉回应。

BIP30 重复交易规则:两块链上'违章'建筑为何被永久豁免 图 2
BIP30 重复交易规则:两块链上’违章’建筑为何被永久豁免 · 图 2

BIP30 说了什么

规则只有一句话:区块不允许包含与链上更早、尚未完全花完的交易同 ID 的交易。完全花完的交易允许重复,这样未来的历史数据修剪不受阻碍。该规则自 2012 年 3 月 15 日零时(UTC)之后的区块起生效,属于共识层软分叉。

为什么有两块”违章”建筑

主网历史上恰好有两个块在规则生效前就包含重复 coinbase——高度 91842 和 91880。它们深埋链中,牵出的资金早已易手,直接”作废”会造成更大的共识灾难。实现上的答案是豁免:Bitcoin Core 源码里对这两个块按高度加哈希精确匹配,BIP30 检查对除这两块外的所有区块生效。源码注释同时解释了这个豁免的第二个理由:让节点在初始块下载期间不必逐块查索引,避免被历史脏数据卡住。

BIP34 才是根治方案

BIP30 的思路是”事后拦截”,代价是每验证一个区块都要查一遍未花费索引。更干净的思路是让 coinbase 天然唯一:BIP34 要求每个块的 coinbase 解锁脚本第一项必须是最小编码的区块高度。主网在 227931 块(2013 年 3 月)起强制执行。有了高度承诺,两个不同高度的 coinbase 想撞 ID,就得让 SHA-256 双哈希现形,实践上不可能。今天的节点在已知链上高于 BIP34 高度的位置可以跳过 BIP30 的数据库查询——前提是源码里已穷举核验过 BIP34 之前所有”承诺高度大于自身高度”的异常块不存在。

今天你还该关心吗

对普通用户:不需要。两个豁免块里的重复输出早已被花光,新的重复 coinbase 在 BIP34 之后造不出来。对开发者:它是理解”软分叉如何在不改写历史的前提下修正规则”的教科书案例——规则向前生效,历史按高度加哈希豁免,共识在裂缝上愈合。它也是”哈希唯一性不是免费的”这一课的最早版本:后来隔离见证为交易 ID 与见证交易 ID 分家做的所有设计,都带着这段历史的影子。

边界说明

本文两个豁免块的高度、BIP34 生效高度等均为链上事实与源码常数,不会随版本变化。描述攻击细节仅为解释防御机制,不提供任何可利用的操作路径。本文只做机制科普,不构成任何投资建议。

把历史串成一条线

把四个年份排开,逻辑链就清楚了:2012 年初重复交易攻击被公开演示,确认数一度不可信;同年 2 月 BIP30 作为应急补丁提出,用”不许覆盖未花完的同 ID 交易”止血,随当年发布的 0.6.0 落地,规则适用于时间戳在 2012 年 3 月 15 日之后的区块;开发者同时意识到逐块查索引的代价不可长期承受,于是 2013 年 3 月 BIP34 用”coinbase 写高度”根治问题;此后节点在 BIP34 之上安全地跳过 BIP30 的昂贵查询。这个序列展示了比特币修缺陷的标准姿势:先用最小改动堵住出血点,再用结构性设计消除问题发生的土壤,最后把旧机制降级为低成本保险。它还留下一个耐人寻味的尾注:两个豁免块提醒所有后来者,共识软件的”正确”从不只是规则文本,还包括对既有历史事实的精确兼容——源码里那几行高度加哈希的硬编码,是整条链不可改写性的活化石。

最后把豁免的边界说清楚:豁免是写进规则文本里的例外名单,只针对 2012 年 3 月那段补丁期间涉及重复交易的两个特定区块,不是任何节点软件里的配置开关,也不给任何后来者开侧门。今天全新同步的节点依然会按同一份规则重放这段历史,两个区块因此永远被承认为有效——这正是比特币处理历史事故的一贯方式:承认既成事实、修好产生事实的漏洞,然后让所有人用同一套规则继续往前走。对研究者的提醒是,任何基于历史完全干净假设的对账脚本,在触达 2012 年 3 月前后的数据时都应当按规则文本的特例做兼容处理,否则会在重复交易上得到一个无法复现的分歧结论,误以为自己同步到了错误的链上。