协议演进 / BIP/比特币改进提案 / BIP-13

BIP-13 pay-to-script-hash 地址格式

定义 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]

版本字节的选择保证 Base58 编码后的首字符稳定:主网字节 5 编码后以 “3” 开头,测试网字节 196 编码后以 “2” 开头。这就是今天以 “3” 开头的地址的来源。

4.2 原文记录的批评与回应

这份 BIP 很短,但如实记下了三条批评:

作者的回应是:本提案只是通往更安全基础设施之路中“最简单的一块”,是相对现状的增量改进,并不打算解决全部可用性与安全问题(更友好的付款机制、收款方身份确认应留给未来的 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” 开头只表示地址里装的是脚本哈希;哈希背后的脚本可以是多签,也可以是其他任意复杂的赎回条件,多签只是最常见的用途之一。光看地址本身,看不出脚本内容。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。