协议演进 / BIP/比特币改进提案 / BIP-388
BIP-388
在描述符之上定义钱包策略:用 @0、@1 占位符加一份外置的密钥信息表,紧凑地表示一整个账户,让硬件签名器也能核对和注册。本 BIP 目前处于已完成状态。
一、档案卡
| 编号 | BIP-388 |
|---|---|
| 标题 | Wallet Policies for Descriptor Wallets |
| 作者 | Salvatore Ingala <[email protected]> |
| 指定日期 | 2023-12-26 |
| 讨论日期 | 2022-05-10 |
| 层级 | Applications(应用) |
| 类型 | Specification(规范类) |
| 状态 | Complete(已完成) |
| 阅读版 | https://bips.dev/388 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki |
二、放在哪一族
描述符族的上层应用:不是再添一种脚本表达式,而是把整套描述符改造成“账户级”的表示。
BIP-380:输出脚本描述符通用操作——钱包策略的语言与它刻意保持相似
BIP-389:多路径密钥表达式 <0;1>——钱包策略的 /** 正是它的双路特例
BIP-379:Miniscript——策略模板在 wsh()、tr() 里可以容纳 Miniscript 模板;注意原文特意澄清:钱包策略(wallet policies)与 Miniscript 的上层“策略语言”(policy language)不是一回事,后者是编译成 Miniscript 的高级语言
BIP-129:比特币安全多签设置(BSMS)——多方如何安全协调一个描述符钱包不在本篇范围,原文把读者指给它;注册流程解决的是其中“用户在签名器屏幕上核对花费条件”这一环
理解顺序是:描述符描述“一个输出脚本集合”,钱包策略描述“一个账户的全部收款与找零描述符”,并且要短到能在小屏幕上核对、能被内存有限的设备保存。
三、它要解决什么
软件钱包与硬件签名设备通常把资金按“账户”划分。签名或展示一笔交易时,受影响的各账户的资金流汇总应当展示给用户看。一个账户逻辑上包含整组收款地址与找零地址;钱包策略就是用一份紧凑、可核查的表示,把描述一个账户所需的全部描述符一次说清。
为什么不直接用描述符?原文指出,描述符是为通用计算机上的 Bitcoin Core 设计的通用灵活语言,与硬件签名设备的典型条件并不合拍:
- 它们是嵌入式设备,内存与算力有限,有的甚至没有持久存储(无状态设计);
- 它们不能导入额外私钥,只能用单个种子经 BIP-32 派生的密钥签名;
- 屏幕很小,展示的信息必须尽量少,用户才可能逐项核对。
而核对恰恰是安全的根基:与签名设备相连的电脑被视为不可信,攻击者可能完全控制它、篡改请求。设备必须保证:用户清楚知道资金受什么“策略”约束,找零确实回到同一策略之下,攻击者无法偷偷换掉策略来盗走或烧毁资金。复杂的 Miniscript 与 Taproot 树让屏幕核对更加困难;同一把扩展公钥在描述符里反复出现(一个 xpub 就有 118 字节),还会让描述符体积成倍膨胀——原文举例:一个 3-of-5 门限钱包配合 MuSig2 密钥路径与 11 片叶子的脚本树,描述符会大到无法人工审查。
解法是“策略注册”:新策略第一次使用前,用户在签名设备上注册它——软件钱包发起注册,设备在安全屏幕上展示策略,用户与可信来源(如纸质备份)比对后批准;有状态的设备把策略存入持久内存,无状态的设备返回一份“注册证明”(例如对策略哈希、名称等元数据做消息认证码)。此后生成地址、在屏幕上展示地址、签名并识别找零,都凭已注册的策略进行,无须每次重复昂贵的核对。本篇定的就是被注册的这份“策略”长什么样;注册流程的细节本身不在本篇范围内。
四、规则本身
4.1 总结构:模板 + 密钥信息表
一份钱包策略由两部分组成:
- 钱包描述符模板:一段脚本表达式,与描述符同形,但其中的密钥不写真实扩展公钥,只写占位符;
- 密钥信息向量:一张外置的表,每项是一条密钥信息——可选的密钥来源信息(方括号内的主密钥指纹与派生路径)加一个序列化的扩展公钥(xpub)。
把冗长的 xpub 从模板里抽走、多处复用同一占位符,模板才短得可审查;把模板编译回描述符则是机械替换(见 4.4)。
4.2 模板中的密钥表达式
模板里的 KEY 由密钥占位符(KP)加上派生后缀构成,后缀永远是以下之一:
/**:最常见的收款/找零写法,等价于/<0;1>/*;/<NUM;NUM>/*:两个互不相同、表示非硬化派生的十进制数——注意这里严格限定为恰好两个选项(收款与找零),不像 BIP-389 允许多个;- 实现自定义的其他合法派生模式(原文专节讨论,须警惕密钥重复风险)。
占位符(KP)或是一个密钥索引(KI):字符 @ 加一个无前导零的非负十进制数,如 @0、@1,@i 指密钥信息表中的第 i 项;或——仅在 tr() 内部——musig(KI_1,...,KI_n) 形式的聚合占位符(1.1.0 版加入)。
每个 KEY 表达式对应最终脚本里一把确定的公钥,因此 BIP-32 层级中的全部派生步都写在表达式里;而占位符本身只对应“该账户全部 UTXO 所用公钥的根”,占位符里不许再带派生步。
模板允许的脚本表达式包括 sh()、wsh()、pkh()、wpkh()、multi()、sortedmulti()、tr() 以及 wsh()/tr() 内的 Miniscript 模板,各自的位置限制与描述符一致。
4.3 附加规则
- 策略至少要有一个占位符及其对应密钥;
- 密钥信息表中各扩展公钥解出的公钥必须两两不同——复用公钥在含 Miniscript 的策略里会带来可锻性等安全问题,也损害隐私;
- 同一占位符若出现两个多路径后缀,两组数值集合必须不相交;
musig占位符内部不许重复同一索引,两组musig占位符的索引集合相同即视为同一占位符; - 密钥信息表应按占位符首次出现的顺序排列:先
@0,再@1,依此类推;跳号或乱序的模板无效。
常见形态示例:单签账户 pkh(@0/**)、wpkh(@0/**)、sh(wpkh(@0/**))、tr(@0/**);多签如 wsh(multi(2,@0/**,@1/**));Taproot 密钥路径的 MuSig2 如 tr(musig(@0,@1)/**);更复杂的 Miniscript 与时间锁继承安排也可以写成模板。
4.4 从策略编译出描述符
由模板与密钥信息表得到对应的多路径描述符,只需两步替换:把每个占位符换成对应的密钥来源信息加 xpub;把每个 /** 换成 /<0;1>/*。反过来,把符合本篇模式的描述符拆回策略也容易,正因为这套语言刻意与描述符保持相似。原文提醒:实现可以只支持策略的一个子集,但限制应明确写清;另外,非标准单签、多签(尤其涉及外部共签人)场景下,种子本身已不足以重新发现有资金的策略,策略备份一旦丢失很可能永久丢币——备份策略与备份种子同样重要,而策略备份泄露只影响隐私、不直接丢币。
4.5 版本与实现
本文档版本 1.1.0(2024-11),该版为描述符模板加入了 musig 密钥占位符支持;1.0.0 于 2024-05-12 发布。原文列出的实现包括:Ledger 的比特币应用(2.1.0 起)、BitBox02 固件(v9.15.0 起)、Blockstream Jade(v1.0.24 起,经 libwally-core)、BTCPay Server(v2.1.1 起,仅支持单签与多签策略的有限子集)与 NBitcoin。采用完全自愿,软件钱包宜同时允许导出普通描述符,以便与不用钱包策略的软件互通。
五、谁必须动
普通持币人:使用硬件签名器时多了一步“注册策略并核对”:首次使用某账户前,在设备屏幕上逐项核对策略并与可信备份比对、批准注册;同时要像保管种子一样保管策略备份(两者缺一,复杂钱包可能无法恢复)。
钱包开发者(软件侧):要支持把账户表示为“模板 + 密钥信息表”、发起注册流程、按 4.4 编译出描述符,并为不用钱包策略的软件保留导出普通描述符的通道。
硬件签名设备开发者:要能解析这套受限语言、在小屏幕上紧凑展示、执行注册与注册证明校验,并凭已注册策略生成地址、识别找零、计算手续费;只能实现子集的,应明确声明范围。
全节点与矿工、共识层:无须改动。钱包策略展开后就是普通描述符与普通脚本,不涉及任何协议规则。
六、现在算不算数,以及一个常见误读
状态为 Complete(已完成):规范文本已经定稿,且原文列出了多个硬件与软件实现。它不改变任何共识或网络规则,“算数”体现在生态采用面上——签名设备与配套软件按同一格式注册、展示、校验策略,用户在不可信电脑前核对的那几行文本才有统一含义。
常见误读:
“钱包策略是一种新的脚本或新的地址类型。”
不对。它既不产生新脚本,也不产生新地址:策略只是把一整个账户的描述符换了一种紧凑表示——模板用 @i 占位、密钥信息外置成表。按 4.4 替换回去,得到的就是 BIP-389 意义下的普通多路径描述符,链上看到的输出与直接用描述符生成的毫无区别。
七、延伸
- 阅读版:https://bips.dev/388
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki
- 相关:BIP-380 描述符通用操作、BIP-389 多路径密钥表达式、BIP-379 Miniscript、BIP-129 安全多签设置、BIP-390
musig()密钥表达式 - 仓库总目录:https://github.com/bitcoin/bips
