协议演进 / BIP/比特币改进提案 / BIP-441
BIP-441
引入新的 Tapleaf 版本 0xC2,在 BIP-440 变操作数预算的约束下,恢复 2010 年被禁用的操作码,并大幅放宽栈元素大小与数值长度限制。本 BIP 目前处于草案状态。
一、档案卡
| 编号 | BIP-441 |
|---|---|
| 标题 | Restoration of disabled script (Tapleaf 0xC2) |
| 作者 | Rusty Russell <[email protected]>, Julian Moik <[email protected]> |
| 指定日期 | 2026-03-25 |
| 层级 | Consensus (soft fork)(共识(软分叉)) |
| 类型 | Specification(规范类) |
| 状态 | Draft(草案) |
| 依赖 | BIP-440 |
| 阅读版 | https://bips.dev/441 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0441.mediawiki |
二、放在哪一族
脚本能力恢复(Great Script Restoration)一族的核心提案,与 BIP-440 是一对:BIP-440 定预算,BIP-441 在预算之内把能力放回来。档案卡的“依赖”一行写的就是 BIP-440。
它只作用于 Taproot 的脚本路径,且只作用于一种新叶子:
BIP-341:Taproot 输出与 taptree 的基本结构
BIP-342:Tapscript 的现行规则;0xC2 叶子未另行定义的操作码,仍按 BIP-342 执行
理解它,要抓住一句话:不是回到旧脚本,而是在新叶子版本里、以新的成本约束重新启用旧能力。
三、它要解决什么
自比特币 v0.3.1 修复 CVE-2010-5137 以来,脚本能力被显著收紧,以防过度计算时间与内存占用带来的拒绝服务风险。原文说,这些早期防护当时是必要的、保住了网络稳定。
代价是:用户对自己输出的花费条件能做的精确控制被拿掉了大半,“无需第三方信任的可编程货币”这一理想长期受挫。
问题在于,当年禁用操作码是因为没有可靠办法限制其最坏成本。如今 BIP-440 的变操作数预算按操作数长度逐项计价、超预算即验证失败,原文认为这正好补上了当年缺的那道防线——于是可以在新叶子版本中恢复到 v0.3.1 之前的脚本能力,同时用预算防住当年那个漏洞的成因。
四、规则本身
4.1 入口:新的 Tapleaf 版本 0xC2
Taproot 叶子版本为 0xc2 时,按本 BIP 执行操作码;未在此明确定义的操作码,与 BIP-342 的定义完全相同。脚本验证失败的情形包括:
- 超出该交易剩余的变操作数预算;
- 任一栈元素超过 4,000,000 字节;
- 栈与 altstack 元素总大小超过 8,000,000 字节;
- 栈元素总数(含 altstack)超过 32,768。
4.2 放宽的三组上限
- 单个栈元素上限:从 520 字节提高到 4,000,000 字节。原文的理由是:把整笔交易放上栈是可预见的用法,以区块大小(4MB)为限顺理成章;
- 栈元素总字节数:新增 8,000,000 字节的总上限。许多栈操作至少要复制一份,故取单元素上限的两倍;
- 栈元素个数:从 1,000 提高到 32,768。原文按最小输出等情形推算一笔交易可能需要区分的元素数量,取 32,768 为合理上限。
内存仍必须有上限,目的始终是防内存型拒绝服务。
4.3 恢复的十五个操作码
v0.3.1 移除的十五个操作码在 0xC2 Tapscript 中重新启用,原文逐字节(byte-by-byte)精确定义其行为,以便推导各自的变操作数成本:
- 拼接类:OP_CAT、OP_SUBSTR、OP_LEFT、OP_RIGHT;
- 位运算类:OP_INVERT、OP_AND、OP_OR、OP_XOR;
- 位移类:原 OP_LSHIFT、OP_RSHIFT 改名为 OP_UPSHIFT、OP_DOWNSHIFT。它们是原始位移,不再是 0.3.0 时代保符号的算术位移,结果也不截去末尾零字节;
- 乘除类:OP_2MUL、OP_2DIV、OP_MUL、OP_DIV、OP_MOD。其中乘除成本可能与操作数长度的平方相关,执行前必须先验算成本、超预算即失败;除数为空或全零时失败。
4.4 数值规则改了:任意长度、无符号
- 取消数值 32 位大小限制,数值按任意长度处理;
- 所有数值一律按无符号(unsigned)处理。负数在 0xC2 中不再原生支持:OP_1NEGATE、OP_NEGATE、OP_ABS 因此改名为 OP_SUCCESS 操作码,执行到即立即成功;
- OP_ADD、OP_SUB、OP_1ADD、OP_1SUB 重新定义为对变长无符号整数运算,结果总是最小长度(无末尾零字节)。减法出现下溢(结果为负)时验证失败;
- 只有算术运算会规范化(normalize)其结果,位与字节运算不会;脚本最终成功条件也改为:栈上恰剩一个元素、且该元素含一个以上非零字节。
4.5 两个哈希操作码的保留限制
OP_RIPEMD160 与 OP_SHA1 在 0xC2 中操作数超过 520 字节即验证失败。原文理由是:对大输入做这两种哈希少有必要,且它们不像 SHA256 那样经过充分优化,故沿用旧的字节上限。
五、谁必须动
普通持币人:现在不必做任何事。本 BIP 仍是草案,未激活;现有的 Taproot 输出与叶子不受影响。
钱包与脚本开发者:现在不必动。若将来激活,只有主动把脚本写进 0xC2 叶子,才用得上恢复的操作码与放宽的上限;同时必须按 BIP-440 预算核算最坏成本。
全节点与矿工:若将来激活,需实现 0xC2 叶子的整套新语义(含逐操作码的成本表)才能完整验证。它使用此前未用过、且原本恒为成功的叶子版本,属于向后兼容的软分叉安排;原文的参考实现标注为进行中。
共识层:改动只落在新叶子版本内。旧叶子、旧脚本的规则一字未动;负数语义、无符号数值、栈上限等新规则也只在 0xC2 内成立,不能拿去解释现行 Tapscript。
六、现在算不算数,以及一个常见误读
状态为 Draft(草案),且依赖同为草案的 BIP-440。今天的主网上没有 0xC2 叶子语义:写了 OP_CAT 等被禁用操作码的现行 Tapscript 并不会因此变得可用,栈元素也仍受 520 字节等现行限制。
常见误读:
“BIP-441 是把脚本原封不动倒回 2010 年。”
不对。它恢复的是能力范围,不是旧规则本身:入口是全新的 0xC2 叶子,执行全程受 BIP-440 预算约束,栈与内存另有新上限,数值改为任意长度无符号,位移改名并改成原始位移,还有三个与负数有关的操作码被改成 OP_SUCCESS。当年的病因(成本不可控)被预算堵上之后,才谈恢复。
七、延伸
- 阅读版:https://bips.dev/441
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0441.mediawiki
- 相关:BIP-440 变操作数预算(本 BIP 的依赖)、BIP-342 Tapscript
- 仓库总目录:https://github.com/bitcoin/bips
