协议演进 / BIP/比特币改进提案 / BIP-13
BIP-13
定义 P2SH 地址格式:地址编码的不再是公钥哈希,而是赎回脚本的哈希;沿用 Base58Check,主网版本字节为 5,地址以 ‘3’ 开头。本 BIP 目前处于已部署状态。
一、档案卡
| 编号 | BIP-13 |
|---|---|
| 标题 | Address Format for pay-to-script-hash |
| 作者 | Gavin Andresen <[email protected]> |
| 指定日期 | 2011-10-18 |
| 层级 | Applications(应用) |
| 类型 | Specification(规范类) |
| 状态 | Deployed(已部署) |
| 阅读版 | https://bips.dev/13 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki |
二、放在哪一族
P2SH 族的地址一环。这一族要分三份文档看:
BIP-12:OP_EVAL,P2SH 的原始设计(后未采用)
BIP-13:本页,地址格式——脚本哈希怎么编码成可书写、可粘贴的地址
BIP-16:Pay to Script Hash,实际部署的赎回校验规则
另一竞争设计 BIP-17(OP_CHECKHASHVERIFY)也在 BIP-13 的参见之列。地址格式与校验规则是两件事:BIP-13 只定前者,无论赎回机制最终选哪一案,收款方都需要一种把脚本哈希告诉付款方的方式。
三、它要解决什么
原文要支持的是“任意复杂的交易”。这里的“复杂”有明确定义:指赎回已收到的币时需要什么信息——普通地址只需要一把 ECDSA 私钥,而复杂条件(多签、托管等)需要的信息要多得多。
设想端到端的安全钱包、向托管交易付款、第三方钱包安全服务这类场景,收款条件没法压进一个公钥哈希里。本质做法是:让地址编码的对象从“ECDSA 公钥的哈希”换成“脚本的哈希”。付款方照旧付给一个地址,脚本细节留到收款方日后花费时再揭示。
四、规则本身
4.1 编码方式
新地址的构造与既有比特币地址完全相同,采用 Base58Check 编码:
base58-encode: [one-byte version][20-byte hash][4-byte checksum]
- 版本字节:主网为 5,测试网为 196。
- 20 字节哈希:将用于赎回这笔币的脚本的哈希。
- 4 字节校验和:版本字节与哈希拼接后做双重 SHA256,取其前 4 字节(与既有地址相同的做法)。
版本字节的选择保证 Base58 编码后的首字符稳定:主网字节 5 编码后以 “3” 开头,测试网字节 196 编码后以 “2” 开头。这就是今天以 “3” 开头的地址的来源。
4.2 原文记录的批评与回应
这份 BIP 很短,但如实记下了三条批评:
- 有人认为比特币地址本应被更友好的付款机制淘汰,再定一种新地址只会鼓励继续用设计不佳的机制;
- 有人认为地址天生不安全:地址不携带身份信息,光凭一串地址无法确信自己在付给谁;
- 截断 SHA256 不是最优的校验和算法,若要引入新地址格式,或许应换更好的检错算法。
作者的回应是:本提案只是通往更安全基础设施之路中“最简单的一块”,是相对现状的增量改进,并不打算解决全部可用性与安全问题(更友好的付款机制、收款方身份确认应留给未来的 BIP);手工输入地址将来会越来越少,既有校验方法在实践中“够用”且已被多次实现,因此没有必要改校验和算法。
4.3 向后兼容
本提案不向后兼容,但失败方式是优雅的:旧实现拿到这种新地址时,会报告地址无效并拒绝创建交易——不会误付,只是用不了。
五、谁必须动
普通持币人/付款方:钱包升级后即可向 “3” 开头地址付款,操作与付给普通地址无区别;脚本里锁了什么条件,付款时既看不到、也不需要知道。
收款方与钱包开发者:按 4.1 的格式把赎回脚本的哈希编码成地址;实现方参考 Bitcoin 源码中的 base58.cpp/base58.h(原文给出的参考实现)。旧软件的用户则会直接被拒绝付款,需要升级。
全节点与矿工:地址只是链下编码格式,本身不进入共识;收到这类地址的币如何校验赎回,由 BIP-16 定义,不在本 BIP 范围内。
共识层:无变化。BIP-13 是应用层的编码规范。
六、现在算不算数,以及一个常见误读
状态为 Deployed:以 “3” 开头的主网 P2SH 地址就是按这份格式编码的,与 BIP-16 的赎回规则配套使用至今。它是比特币地址体系里第一次让“地址”指向一段脚本而非一把公钥,后来的地址演进都建立在“付款方只需面对一个短串、条件细节后置”这个思路上。
常见误读:
“以 3 开头的地址就是多签地址。”
不对。按 BIP-13 的定义,“3” 开头只表示地址里装的是脚本哈希;哈希背后的脚本可以是多签,也可以是其他任意复杂的赎回条件,多签只是最常见的用途之一。光看地址本身,看不出脚本内容。
七、延伸
- 阅读版:https://bips.dev/13
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki
- 相关:BIP-12(P2SH 原始设计)、BIP-16(P2SH 赎回规则)、BIP-17(另一竞争设计)
- 仓库总目录:https://github.com/bitcoin/bips
