协议演进 / BIP/比特币改进提案 / BIP-87
BIP-87
为确定性多签钱包定下与脚本类型无关的统一层级 m/87’/…,把脚本交给描述符表达,密钥派生不再一脚本一路径。本 BIP 目前处于已完成状态。
一、档案卡
| 编号 | BIP-87 |
|---|---|
| 标题 | Hierarchy for Deterministic Multisig Wallets |
| 作者 | Robert Spigler <[email protected]> |
| 指定日期 | 2020-03-11 |
| 层级 | Applications(应用) |
| 类型 | Specification(规范类) |
| 状态 | Complete(已完成) |
| 阅读版 | https://bips.dev/87 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki |
二、放在哪一族
多签钱包的派生层级族,也是单签路径族的一次“分家”:
BIP-32:派生算法根基
BIP-43:purpose 约定——本 BIP 是它的一个具体应用
BIP-44:多账户层级——单签按脚本分 purpose(44’/49’/84’)的源头
BIP-45:早期的确定性 P2SH 多签结构,被本 BIP 点名批评
BIP-67:公钥排序——其作用被描述符的 sortedmulti 吸收
BIP-129:Bitcoin Secure Multisig Setup——用描述符模板组织多方密钥记录,与本 BIP 配套
BIP-174:PSBT——描述符中的密钥来源信息与之兼容
一句话定位:单签继续走“一脚本一 purpose”,多签改走 BIP-87 这一条与脚本无关的路。
三、它要解决什么
离线多签钱包越来越易用,描述符语言与 PSBT 等新工具也已就位,但多签的派生方案却没有跟上。原有两种做法都有毛病:
- BIP-45:路径
m/purpose'/cosigner_index/change/address_index。它把脚本钉死为 P2SH 一种;又要求按 cosigner_index 排序各共签人的公钥来拼路径——而描述符用 multi / sortedmulti 本就能定顺序或按字典序排序,这一步纯属多余,还要在把密钥记录发给协调者之前多绕几轮通信。 - 业界惯用的 m/48’:路径
m/purpose'/coin_type'/account'/script_type'/change/address_index,把 script_type’ 塞进路径(P2SH-P2WSH=1、P2WSH=2、未来脚本=3……)。脚本本就由描述符说明,路径里再记一份是重复劳动,而且每出一种新脚本就要维护、更新这张映射表。
根源在于:单签的“一脚本一 purpose”适合单签,是因为单签仅凭私钥信息就能恢复;多签恢复本来就必须额外保存全部共签人公钥等信息,这些信息恰好由描述符统一承载。既然描述符已经管脚本,派生路径就不该再把密钥与脚本混在同一层。
因此本 BIP 只针对多签钱包:若把同样的脚本无关层级套到单签上,用户恢复时要么额外备份描述符,要么让钱包对每个账户试遍所有脚本类型,得不偿失。
四、规则本身
4.1 五层路径
m / purpose' / coin_type' / account' / change / address_index
- purpose’:常数
87',按 BIP-43 的建议取值,表示此子树按本规范使用;硬化派生。 - coin_type’:一个种子可用于多个网络,此层为每个网络分一棵子树,避免跨网络重用地址;主网为 0,测试类网络(testnet、regtest、signet)为 1;硬化派生。
- account’:把密钥空间切成互不混用的独立账户,像银行账户一样分用途(公开收款、储蓄、日常支出等),从 0 起顺序编号;硬化派生。关键纪律:每新建一个钱包、每生成一份新的公私钥记录,都必须递增 account’——在把密钥记录发给协调者之前就要先递增,以同时防 ECDSA 与 Schnorr 签名之间、不同脚本类型之间、同类钱包之间的密钥重用。
- change:0 为外部链(对外收款地址),1 为内部链(找零地址);非硬化派生。
- address_index:地址序号,从 0 起顺序编号;非硬化派生。
原文附有主网/测试网、第一/第二账户、外部/内部链的完整路径示例表。
4.2 密钥排序
支持描述符的钱包天然支持按 BIP-67 的确定性排序:描述符的 sortedmulti 函数保证所有参与方从同一组公钥派生出相同的多签地址与脚本,不需要再在路径里做任何排序约定。
4.3 地址发现与间隔上限
地址的生成与发现以多签描述符(或由各共签人密钥记录合成的描述符模板)为准,描述符应带密钥来源信息以最大兼容 BIP-174。例如模板 wsh(sortedmulti(2,[xfpForA/87'/0'/0']XpubA/**,[xfpForB/87'/0'/0']XpubB/**)) 配合路径限制 /0/*,/1/*,展开为收款与找零两条具体描述符;发现时两条都要导入。
地址间隔上限(gap limit)为 20:连续遇到 20 个未用地址即认为其后没有已用地址、停止扫描;软件在用户于外部链上生成过多未用地址、逼近上限时应给出警告。
4.4 兼容性
凡描述符(及具体钱包实现)支持的脚本都与本 BIP 兼容。反过来,采用本 BIP 的钱包必然是描述符钱包,因此每个共签人恢复时必须同时备份私钥信息与描述符——这不算额外负担,因为任何 M-of-N 多签恢复本来就需要在 M 份种子之外再凑齐全部共签人的公钥,描述符只是把这些信息以标准格式、带来源信息与检错能力装在一起。
五、谁必须动
普通持币人(多签用户):备份内容从“种子”升级为“种子 + 描述符”,缺了描述符就无法重建多签钱包;新建钱包或新增密钥记录时留意钱包是否递增了账户层。
钱包开发者:实现 m/87’/… 层级与 sortedmulti 排序,按描述符做地址发现并执行 20 的间隔上限与超限警告;协调流程中在发出密钥记录前递增 account’。
协调者/多方协作软件:以描述符模板合成各共签人的密钥记录,不再依赖路径排序公钥。
全节点与矿工、共识层:无须改动,也不感知本 BIP。
六、现在算不算数,以及一个常见误读
状态为 Complete(已完成)。按现行状态体系,Complete 表示规范本身已经写完、定稿,可供实现采用;它不等于共识激活,也不要求全网钱包统一改用——多签钱包是否遵循,仍是各自实现的选择。
常见误读:“既然 BIP-87 的路径与脚本无关,我换钱包恢复时只带种子就够了。”
不对。这正是本 BIP 与单签路径的分界:多签恢复从来都需要全部共签人的公钥信息,本 BIP 把它明确托付给描述符。只带种子、不带描述符,恢复不出原来的多签地址集合。
