BIP-110 规范(中文译本)
本文为 BIP-0110:Reduced Data Temporary Softfork 的中文翻译与通俗解读,旨在帮助中文读者理解该提案的目标、规则与影响。
原文参考:bip-0110.mediawiki
通俗解读
这份提案想解决的问题是:比特币区块链不应该变成“任何数据的存储盘”,因为这会让运行节点的人承担额外成本,也会抬高转账费用。BIP-110 提议在共识层暂时限制可以嵌入区块的任意数据大小,确保比特币继续以“货币网络”为核心目标。
具体来说,它会在一年内限制输出脚本和见证数据的大小,并临时禁用一些容易被用于塞数据的 Taproot 形式。同时,BIP-110 明确保护已存在的资金:在激活前创建的 UTXO 不受新规则影响。
这是一项临时软分叉:激活后约一年这些限制自动失效。支持者认为它能为比特币争取时间,避免数据滥用牵引社区方向;反对者则关注它对新功能的限制。无论立场如何,理解它的规则与权衡都很重要。
规范元数据
摘要
在共识层临时限制数据字段大小,以纠正因标准化支持任意数据而造成的激励扭曲,并将优先事项重新聚焦于提升比特币作为货币的能力。
版权
本文档依据 BSD 3 条款许可证发布。
规范
在为期一年的临时部署期间,区块会额外应用以下规则:
- 新的输出 scriptPubKey 超过 34 字节则无效;除非首个操作码为 OP_RETURN,此时最多允许 83 字节。
- OP_PUSHDATA* 的负载以及见证栈元素超过 256 字节无效,BIP16 scriptSig 中的 redeemScript 推送除外。
- 花费未定义的见证版本(或 Tapleaf 版本)无效(即不属于 Witness v0/BIP141、Taproot/BIP341 或 P2A)。创建未定义见证版本输出仍然有效。
- 包含 Taproot annex 的见证栈无效。
- Taproot 控制块超过 257 字节无效(相当于超过 128 个脚本叶子的默克尔树)。
- 包含 OP_SUCCESS* 操作码的 Tapscript 无效(即便从未执行)。
- 执行 OP_IF 或 OP_NOTIF 的 Tapscript 无效(不论结果)。
花费在激活高度之前创建的 UTXO 的输入不受新规则影响。软分叉到期后,所有高度的 UTXO 再次不受限制。
动机
为了保护比特币作为互联网原生货币的预期功能,比特币社区历史上一直对在交易中嵌入任意数据的技术保持警惕甚至反对。
必须始终抵制此类数据嵌入,以免它变成网络的依赖并产生负外部性,尤其会给节点运营者带来负担。
自 2022 年“铭文”(inscription)漏洞被利用以来,在比特币交易中嵌入任意数据的趋势迅速出现,为节点运营者带来明显且不必要的负担,同时将开发重点与激励从比特币作为可靠、无许可、无国界货币的核心目的上转移。
本提案旨在通过拒绝将数据存储标准化为共识层支持的用例,让比特币回到成为全球货币的轨道。
它通过共识临时否定若干最具破坏性的滥用方式,同时保留所有已知的货币用途。
具体而言,本提案会使所有连续嵌入超过 256 字节任意数据的方法无效;同时使几乎专用于数据嵌入的大型 scriptPubKey 与 Tapleaf 形式无效;并在共识层恢复长期存在的 OP_RETURN 83 字节策略限制。
在软件开发中,禁用不受支持的用例是常见做法,否则会迅速变得不可持续并导致开发停滞。
因此,这些新规则的激活向外界释放了明确讯号:任意数据存储会持续被抵制,不应被允许拖偏网络的优先事项。
它也强化了比特币作为抗审查支付系统的核心功能,因为数据存储与支付不公平地竞争区块空间,使支付成本被不必要地抬高。这会鼓励用户依赖第三方支付处理器,从而让支付更容易被审查。
最后,它通过重新强调降低节点运营成本的长期承诺,提高节点网络的去中心化程度。
比特币应当“只做一件事,并把它做到最好”。拒绝数据存储后,本 BIP 将开发者从无止境的范围蔓延中解放出来,使他们能聚焦最关键的目标:比特币作为货币的成功。
理由
规范细节
为什么将 scriptPubKey 限制为 34 字节?
未花费的 scriptPubKey(不含 OP_RETURN)必须永久存入 UTXO 集,而节点必须把它们放在快速存储介质中且无法裁剪。快速存储(通常是 RAM)每字节成本远高于慢速、非易失性存储,因此 UTXO 集越大,节点运营者的负担越重,去中心化也会受损。
这些成本直接由发送方承担,而非接收方。由于这些原因,现代使用实践中脚本几乎都不超过 34 字节;实际的花费条件已转移到见证区,scriptPubKey 仅通过哈希提前承诺。
此外,大型 scriptPubKey 除了是数据嵌入载体,还可被滥用生成需要很长时间验证的恶意交易与区块(“投毒区块”)。因此,大型 scriptPubKey 既有高滥用风险又无现实收益,本提案将其判为无效。
OP_RETURN 怎么办?为什么不彻底移除它?
OP_RETURN 输出可证明不可花费,因此节点无需将其存入 UTXO 集。历史上允许最多 83 字节,是为了避免其他输出脚本出现不可证明不可花费的垃圾数据。除了一些在 coinbase 输出中使用 OP_RETURN 的承诺方案(尤其是 SegWit)外,OP_RETURN 并非任何已知用例的最佳方案。
随着 pay-to-contract 与 Taproot 的引入,现在也可以在 Taptree 中承诺外部数据,使 OP_RETURN 的假设用途进一步过时。
然而,为避免破坏仍包含此类输出的遗留协议,本提案仍允许这些输出。
为什么将其他数据限制为 256/257 字节?
在现代压缩技术下,一张图片可能只需 300~400 字节即可表示。图片是最具破坏性的数据存储用例之一,需求巨大且会引发高费用与 UTXO 膨胀,同时还可能包含大多数节点运营者反感的内容。
256 字节(2048 比特)也足以承载合理规模的加密数字需求,进一步强化比特币作为货币网络的定位。
垃圾数据不会被拆成多个字段吗?
完全阻止隐写是不可能的,但限制数据大小能确保滥用必须以非连续、被掩盖的方式嵌入到有既定含义的结构中(如脚本代码或结构本身)。对比特币而言,数据具有与垃圾数据不同的含义,任何“重新拼装”都需要外部代码来完成(因为理论上任何数据都能被转换成其他数据)。
要求用户将文件拆分成最多 256 字节的小块,不仅提高了费用与工作量,也传达了明确讯息:数据存储滥用是不受欢迎的,更谈不上被认可或支持。
为什么对 BIP16 redeemScript 有例外?
redeemScript 本身是另一段脚本,随后会被执行,其内容同样受 OP_PUSHDATA* 限制。限制它不仅没有必要,还会削弱脚本的正常能力,并可能影响真实的合法用法。
为什么让花费未定义见证/Tapleaf 版本无效?
这些版本目前未定义,为了未来升级的最大灵活性,相关见证栈当前在长度上是完全无限制的。未来升级通常需要一年以上的协调,因此本软分叉不会真正阻碍升级,只是在过渡期防止滥用。
为什么不禁止发送到未定义见证版本?
这会要求交易发送方在发送前检查见证版本,并在新见证版本准备启用时进行额外协调。
为什么不允许用空见证花费未定义见证版本?
这没有现实用例,却会迫使节点跟踪这些 UTXO 以备潜在花费。将花费直接判为无效,可以让节点把它们放在不需要高速访问的慢存储中,直到软分叉过期。
在合理规划下,这也能让未来升级的钱包在升级激活前就能接收资金。
为什么让 Taproot annex 无效?
annex 当前是未定义且无限大小的数据。它为未来升级预留,但目前没有合法用途。未来升级需要超过一年的协调,因此本软分叉不会真正限制它,只是在此期间防止滥用。
为什么 Taproot 控制块限制为 257 而不是 256 字节?
控制块由一系列哈希组成,用来证明 Tapscript 在 Taptree 中的位置,并额外包含一个字节用于叶子版本与奇偶标识。详见 BIP 341。
为什么让 OP_SUCCESS* 无效?
OP_SUCCESS* 预留给未来升级。原因与未定义见证版本相同。
为什么让 OP_IF/OP_NOTIF 无效?
OP_IF/OP_NOTIF 起源于 Taproot 之前的脚本,用于根据条件执行不同子脚本。在 Taproot 中,这些条件可以在链下评估,只揭示真正执行的验证路径。
当条件满足时,通常应走 keypath 花费路径,从而避免公开任何脚本。
OP_IF 在 Tapscript 中不仅冗余,而且常被滥用来注入执行中被跳过的垃圾数据。虽然无法完全阻止隐写,但关闭这一缺口几乎零成本就能消除一种常见滥用,并传递出不欢迎此类行为的讯号。
OP_IF 在 Tapscript 中确实存在一些潜在实验用途,详见“权衡”部分。
为什么提案如此简单?
可以构想出更复杂、在创新与安全之间更平衡的方案,但这需要大量重构和审查,会延迟部署,而现在的变化已经很紧迫。
因此,本提案刻意保持规则简单,以减少审查时间,并避免因忽视意外副作用而引入风险。
为什么软分叉是临时的?
这些限制会严重束缚未来升级,可能迫使升级采用硬分叉而非软分叉。一些限制也并不理想,但更好的限制需要更复杂的开发与测试。
因此先部署一个简单的限制,可以避免“完美主义”阻碍“足够好”的方案,同时为未来升级更优限制留出空间。
在接下来的一年里,开发者可以提出更长期的方案,在不引入这些权衡或粗糙限制的情况下满足协议需求。
权衡
有什么权衡吗?
- 将 Taproot 控制块限制为 257 字节会直接约束链上脚本树大小,这可能会复杂化甚至阻碍依赖大量可执行脚本的高级智能合约(如 BitVM)。在最坏情况下,这些用例可能需要等到软分叉到期。由于它们仍处于早期开发阶段,未来一年使用测试网或侧链应足够。
- 升级钩子无法用于其他软分叉。由于新增操作码的软分叉通常需要至少一年才能激活,这不太会成为现实问题。
- 一些钱包(如 Miniscript)习惯创建包含 OP_IF 的 Tapleaf。为降低资金被冻结一年的风险,本提案豁免花费激活前创建的输出,并在锁定与激活之间提供两周宽限期。
Taproot 控制块限制是否过于严格?
可能是。此前的限制允许 340,282,366,920,938,463,463,374,607,431,768,211,456 个脚本,这显然远超任何实际需求。257 字节允许 128 个脚本,足以覆盖现代复杂交易。
但它可能对 BitVM 等高级链下功能过于严格。这是我们为了短期收益不得不接受的取舍。如果软分叉被接受,意图是在过期后放宽这一限制,并采用尚未提出的新方法允许更大的树。
需要注意的是,taptree 的非脚本用途(或非比特币 L1 脚本)并不受此限制:128 个叶子中的任意一个都可以扩展成比本软分叉限制更深的默克尔树。
Taptree 本来就应当是不平衡的吗?
优化的 taptree 往往会偏向更可能执行的脚本,但这只是可选;如果需要,仍可以使用完整容量(本例为 128 个脚本)。
此外,在理想情况下,taptree 或其默克尔分支根本不会发布:各方应在链下评估花费条件并通过 keypath 重新广播交易。
Tapscript 主要用于一方不可达或不合作的情况;它的存在通常只是为了让故意不合作变得没有意义。一个例外是使用 NUMS 点来限制输出只能通过脚本路径花费的协议。
资金会被冻结或丢失吗?
理论上可能。本提案尽最大努力避免影响已知用例,并有充分理由相信不会影响任何人。但确实存在一些涉及预签名 Taproot 交易的实验用例可能受影响。
具体而言:
- OP_IF/OP_NOTIF 限制可能临时使当前版本的 Miniscript 编译器生成的某些边缘 Tapleaf 无效。目前没有已验证的生产用例,但某些流行钱包理论上可能生成它们。
- Taptree 深度限制会使深度超过 7 层的 Tapleaf 无效。由于常见花费条件通常放在树的上层,因此这些资金几乎总是可通过上层 Tapleaf 轻松花费。
在两种情形中,资金可以通过树中的其他 Tapleaf 或 keypath 花费(除非 keypath 被 NUMS 点明确失效)。
只有满足以下所有条件,资金才可能被冻结或丢失:
- UTXO 为 pay-to-Taproot(P2TR);
- UTXO 位于预签名交易中;
- UTXO 必须在一年部署期内被确认且花费;
- 用户选择的 Tapleaf 包含 OP_IF/OP_NOTIF 或深度超过 7;
- keypath 无法用于花费,并且树中没有其他可用 Tapleaf(则资金被冻结);或存在可用 Tapleaf 但产生意外花费(则资金丢失)。
换言之,资金完全不受影响的情形包括:
- 不使用 Taproot;
- 以标准、常见方式使用 Taproot;
- 部署期间需要使用的 UTXO 在激活前确认;
- 预签名交易未使用违反新规则的 Tapleaf;
- 即便使用违反新规则的 Tapleaf,也无需在部署期内同时确认并花费;
- 即便必须在部署期内确认并花费,也可通过 keypath 或树中其他 Tapleaf 花费。
本提案尽力避免资金被冻结或丢失,但无法证明绝对无人受影响。因此是否激活,取决于社区是否认为拒绝数据存储值得这份权衡。
为激活做好准备,建议用户现在开始迁移可能受影响的资金。若激活通过,锁定与激活之间将至少有两周的缓冲期,留给用户迁移剩余资金。
替代方案 / 其他思路
为什么不让手续费市场管理数据存储?
手续费市场用于根据经济紧迫性优先排序交易。然而,链上数据存储与支付属于完全不同的市场,激励结构也不同。
货币交易的手续费激励矿工打包一次性支付,矿工提供的是一次性支付的安全确认服务。支付确认后,支付方并不会从网络中获得更多收益,除了维护交易历史的完整性(这是所有节点运营者愿意承担的,因为否则比特币无法作为货币运行)。
相反,数据存储的手续费仍只支付给打包该数据的矿工,但存储负担落在所有节点运营者身上,他们没有得到手续费却需要永久下载、存储并提供这些数据。
这意味着矿工获得一次性费用,节点却被迫无偿提供高可用、不可审查的数据存储服务,尤其当内容令人反感时,节点的负担更大。
OP_RETURN2/“blobspace” 让节点可选存储如何?
这类方案过去已多次尝试。再次尝试也无妨,本提案并不阻止它。但这些方案依赖发送者配合,而发送者通常希望强制内容进入不愿意的节点(否则早就用其他分发方式)。此外,它们也无法解决令人反感内容的问题。
为什么不禁用 PUSHDATA 操作码/取消见证折扣/只限制 annex 长度/限制整体见证或交易大小/让软分叉永久/让 OP_RETURN 更便宜?
这些都是有趣的想法,但会增加实现复杂度。本提案优化目标是简单且易审查,以便快速部署。若社区决定尝试这些方案,本提案鼓励在它到期后再推进。
为什么不去掉一部分限制?
本提案在不增加复杂度的前提下,尽可能强烈地否定“任意数据存储”用例。放松任何规则都会降低达成目标的效果,而收益有限。
垃圾交易不应该在中继策略中解决吗?这是否意味着策略无效?
策略仍是对抗垃圾交易的最佳位置,但它无法保证 100% 有效,尤其当恶意行为者是矿工时。软分叉能降低这类极端风险。
这能彻底解决垃圾交易吗?
不能。垃圾交易不可能完全消除,通常应靠策略和过滤来处理。软分叉的作用是要求那些想存储大文件的人把数据伪装成金融数据或拆分成多个数据推送。即便发生,这也应被视为滥用,而本 BIP 强化了数据存储不是受支持用例的结论。
为什么不处理非比特币代币?
非比特币代币种类繁多,很多是骗局吗。它们更适合在策略层处理,而本提案也不试图彻底消除垃圾数据。
这是否是滑坡?今天禁数据,明天会禁我们不喜欢的用例吗?
不会。这些规则虽然是共识层的新规则,但它们只是把长期原则写入共识,以应对去中心化与货币用途的系统性威胁。
软分叉不试图限制货币活动或交易有效性。通过尽可能限制数据存储用例,它强化了比特币作为可靠、无许可货币的长期保障。
将系统性风险与货币用途严格区分,为未来过度干预提供了清晰防线。
软分叉明确是临时的,也再次强调这是针对特定危机的干预,而非新的发展方向。如果你不采取后续行动,它将在一年后过期。即便未来有跟进提案,你仍可选择拒绝。
这会破坏用户空间吗?
会。本提案刻意破坏了“数据存储”用户空间,以表达该用例不受支持。我们尽力避免破坏货币用例,虽然理论上仍可能影响,详见“权衡”部分。
向后兼容性
在极少数场景下,资金理论上可能被冻结或丢失,详见“权衡”部分。
如果本提案激活,Miniscript 编译器需要在规则生效期间避免生成违反新规则的脚本。
在比特币链上存储任意数据的用户应开始寻找其他存储方式,例如 Nostr、IPFS、BitTorrent、云存储等,因为比特币网络将不再支持该用例。
其他所有已知用例不受影响。
参考实现
https://github.com/bitcoinknots/bitcoin/compare/29.x-knots...dathonohm:bitcoin:uasf-modified-bip9
部署
本次部署使用修改版 BIP9,参数如下:
- name:reduced_data
- bit:4
- starttime:1764547200(约 2025 年 12 月 1 日)
- timeout:NO_TIMEOUT
- min_activation_height:0
- max_activation_height:965664(约 2026 年 9 月 1 日)
- active_duration:52416 个区块(激活后约 1 年)
- threshold:1109/2016(55%)
与 BIP9 的差异
阈值降低(55% 而非 95%):标准 BIP9 的 95% 阈值适用于永久共识变更,需要几乎全体矿工准备就绪。由于拒绝数据存储具有紧迫性且软分叉仅为期一年,更低阈值更合理。
无 timeout,改用 max_activation_height:标准 BIP9 在未达阈值时会基于时间转为 FAILED。本部署将 timeout 设为 NO_TIMEOUT,并使用类似 BIP8 的高度上限 max_activation_height。在高度 963648(距离 max_activation_height 前一个难度周期)进入 LOCKED_IN,并在高度 965664 进入 ACTIVE。
强制信号期:类似 BIP8,本部署在强制锁定前的一个难度周期内要求强制信号(区块 961632 到 963647;锁定不晚于 963648)。在此窗口内,不发出 bit 4 信号的区块会被判无效。强制信号在进入 LOCKED_IN 后结束。
通过 active_duration 过期:标准 BIP9 在 ACTIVE 后永久有效。本提案引入 active_duration(52416 个区块,约 1 年),使部署为临时而非永久。状态机仍停留在 ACTIVE,但共识规则只对高度小于 activation_height + active_duration 的区块生效。超过 52416 个区块后,规则不再执行,UTXO 再次不受限制。
状态转换:状态机流程如下:
- DEFINED:starttime 前的初始状态。
- STARTED:starttime 之后;矿工可用 bit 4 发信号。
- LOCKED_IN:当上一周期达到阈值后,在下一个难度周期起始进入;强制信号(961632-963647)确保不晚于 963648 进入。
- ACTIVE:LOCKED_IN 之后一个难度周期进入;规则在 active_duration 内生效。
timeout 被禁用,因此不会进入 FAILED。ACTIVE 为最终状态;之后不再有状态转换。到期后矿工继续发信号也不会产生影响,因为部署已不在 STARTED 状态,信号只影响 STARTED → LOCKED_IN 的转换。active_duration 结束后,部署仍处于 ACTIVE,但规则不再执行。状态机中没有单独的 EXPIRED 状态。
致谢
原始草案与建议:Luke-Jr