协议演进 / BIP/比特币改进提案 / BIP-345
BIP-345
提出用 OP_VAULT 与 OP_VAULT_RECOVER 两个 Tapscript 操作码实现带延迟提取与恢复路径的金库契约,让私钥被盗时仍有机会把币抢救回来。本 BIP 目前处于已关闭状态。
一、档案卡
| 编号 | BIP-345 |
|---|---|
| 标题 | OP_VAULT |
| 作者 | James O'Beirne <[email protected]> Greg Sanders <[email protected]> |
| 指定日期 | 2023-02-03 |
| 讨论日期 | 2023-01-09 |
| 层级 | Consensus (soft fork)(共识(软分叉)) |
| 类型 | Specification(规范类) |
| 状态 | Closed(已关闭) |
| 接替文档 | Proposed-Replacement: BIP-443 |
| 阅读版 | https://bips.dev/345 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0345.mediawiki |
二、放在哪一族
契约(covenant)与金库(vault)族。它不是孤立的操作码提案,而是和几件已有或在提的工具拼在一起用:
BIP-119:OP_CHECKTEMPLATEVERIFY,把最终提取锁定到一组确定的输出
BIP-112:OP_CHECKSEQUENCEVERIFY,提供相对时间锁,也就是金库的“等待期”
BIP-340、BIP-341、BIP-342:Schnorr 与 Taproot/Tapscript 基础,金库结构建在 Taproot 的 taptree 上,本 BIP 借 OP_SUCCESSx 占位操作码做软分叉升级
原文还提到,它是对更早想法的收敛:2016 年的 Bitcoin Vaults 讨论、2021 年的 TAPLEAF_UPDATE_VERIFY 提案都指向同一种“只替换一个叶子、其余花费条件原样保留”的机制。
档案上它已 Closed,并给出接替文档 BIP-443。读它主要是为了理解“专用契约”这条路线怎样设计金库,而不是把它当作现行规则。
三、它要解决什么
托管比特币的核心风险是私钥一旦被盗,币可以被立刻、不可逆地转走,持有人几乎没有干预窗口。金库的思路是反过来给花费加一道程序:
- 币先锁进金库结构;
- 正常提取必须先发起“触发”,然后等一段可配置的延迟(spend delay);
- 延迟期内若发现异常——比如私钥已泄露、有人在偷币——持有人可以随时走预设的“恢复路径”(recovery path),把币扫到安全处;
- 延迟期满且无人干预,提取才按触发时定下的目标完成。
恢复路径因此可以做得极端安全:可以是纸上保存的私钥、不同厂商设备组成的 2-of-3 多签,甚至地理上分散保存——反正它平时根本用不上,只有最坏情况才启用。
在现行共识规则下模拟金库,只能靠预签名交易加一次性密钥,原文列了它的硬伤:金额与提取模式必须预先定死、最终目标要经过一个预先定好的中转地址、手续费方案在建库时就得定、地址复用会丢币、代表金库的交易数据必须永久保存、每存一笔新余额都要重做一遍建库仪式。BIP-345 想用链上契约去掉这些预计算负担。
它的设计目标还有:同一金库配置可反复接收存入、恢复与触发可批量处理、可部分提取而不必重建库、提取目标与手续费都在提取时动态决定。
四、规则本身
4.1 两个新操作码
以软分叉方式重定义两个 Tapscript 占位操作码:
OP_VAULT:重定义 OP_SUCCESS187(0xbb),负责“触发”提取;OP_VAULT_RECOVER:重定义 OP_SUCCESS188(0xbc),负责走恢复路径。
4.2 金库的结构
币存入一个 Taproot 输出,其 taptree 至少含两个叶子:
- trigger(触发)叶:含触发授权(如一把触发钥的签名校验)与
OP_VAULT调用; - recover(恢复)叶:含恢复输出的 scriptPubKey 哈希与
OP_VAULT_RECOVER。
内部公钥通常设为与恢复路径相同的控制方式,或设为不可花费的 NUMS 点,强制只能走脚本路径。
4.3 OP_VAULT:触发时“换一个叶子”
触发交易花费金库时,OP_VAULT 从栈上读取leaf-update 参数(要写入的新脚本主体及其数据项)、触发输出下标、可选的“重新入库”(revault)输出下标与金额,然后验证:
- 触发输出必须仍是 v1 见证程序,其 taptree 与原金库只差当前叶子:当前叶子被替换为指定脚本(典型写法是
OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKTEMPLATEVERIFY,即相对时间锁 + 锁定最终输出),其余叶子——包括恢复叶——原样保留; - revault 输出(若有)的 scriptPubKey 必须与被花费的金库输入完全相同,金额按参数划回;
- 金额通过“延迟检查”(deferred checks)在全部输入验完后汇总核对,保证金库资金不被触发交易吞掉;
- 每次
OP_VAULT求值扣减 60 的 sigops 预算,超支即失败。
这样,提取目标(CTV 哈希)在触发时才指定,而不是建库时;延迟时长则由建库时的 OP_VAULT 参数定死,触发者改不了。
4.4 OP_VAULT_RECOVER:随时抢救
OP_VAULT_RECOVER 从栈上读取恢复输出的 scriptPubKey 哈希(32 字节)与输出下标,验证该输出 scriptPubKey 的带标签哈希(tagged hash,标签为 “VaultRecoverySPK”)等于给定哈希,并排队延迟检查,要求该输出金额不少于本输入全部金额。条件满足,币就只能去往预设的恢复地址,偷币者无法改道。
恢复可以在最终提取确认前的任何时刻发起。恢复叶前面可加一段授权脚本(authorized recovery),也可不加(unauthorized recovery):不加时,谁知道金库位置与恢复路径都能发起恢复——币只能去恢复地址,偷不走,但容易被抢跑与钉住攻击(pinning)干扰。
4.5 策略层配套(非共识)
为防钉住攻击,原文还规定了交易策略:恢复交易必须可替换(满足 BIP-125 的 opt-in RBF 条件,或交易版本为 3);无授权恢复的交易最多两个输出,多出的一个只能是临时锚点(ephemeral anchor)输出。
4.6 金库不是 OP_VAULT 一个人完成的
原文说得很直白:OP_VAULT 本身只提供“换叶子”与“按哈希锁定恢复输出”两件事。完整的延迟提取还靠 OP_CHECKSEQUENCEVERIFY 给出相对时间锁、靠 OP_CHECKTEMPLATEVERIFY 把最终提取锁定到确定输出。原文也因此提出应与 BIP-119 一同部署。
五、谁必须动
普通持币人:主网并无此规则,无需任何动作。将来若用金库钱包,还必须有人(自己或瞭望塔)盯链:发现异常触发后,要在延迟期内发起恢复,没人监控的金库等于没有保险丝。
钱包开发者:要实现建库、触发、部分提取、重新入库、恢复的全套流程,以及批量操作、动态手续费与地址派生(原文提醒:无授权恢复下,共用同一恢复参数的金库应预期被一并恢复)。
全节点与矿工:这是一次共识软分叉,且引入了“全部输入验完再汇总核对”的延迟检查机制,验证逻辑的改动比普通新操作码更大。不升级的节点会把用了新语义的脚本按旧 OP_SUCCESS 规则直接放行——这正是软分叉的兼容方式。
托管机构:是原文设想的主要受益者之一,但同样要承担监控与恢复演练的运维责任。
六、现在算不算数,以及一个常见误读
状态为 Closed:该提案已关闭,未在主网激活,档案给出的接替文档是 BIP-443。因此今天任何钱包都不能在主网上靠 OP_VAULT 建库;它现在的价值是设计文献——把“延迟 + 可中断提取”这件事的完整需求、攻击面(钉住、抢跑、批量恢复)与一种专用契约解法写清楚了。
常见误读:
“有了 OP_VAULT,私钥被盗也不怕,币自动就安全了。”
不对。第一,它从未激活。第二,即便激活,金库也不是自动保险:提取延迟只给你一个干预窗口,前提是有人实时监控链上动静、且恢复路径的密钥还安全可用。监控缺位或恢复钥丢失,金库照样救不回来。
七、延伸
- 阅读版:https://bips.dev/345
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0345.mediawiki
- 相关:BIP-119 OP_CHECKTEMPLATEVERIFY、BIP-112 OP_CHECKSEQUENCEVERIFY、BIP-341 Taproot、接替文档 BIP-443
- 仓库总目录:https://github.com/bitcoin/bips
