协议演进 / BIP/比特币改进提案 / BIP-174
BIP-174
定义部分签名比特币交易(PSBT)的二进制格式与处理角色,让不同钱包能接力补齐信息、签名并合并同一笔未完成交易。本 BIP 目前处于已部署状态。
一、档案卡
| 编号 | BIP-174 |
|---|---|
| 标题 | Partially Signed Bitcoin Transaction Format |
| 作者 | Ava Chow <[email protected]> |
| 指定日期 | 2017-07-12 |
| 层级 | Applications(应用) |
| 类型 | Specification(规范类) |
| 状态 | Deployed(已部署) |
| 阅读版 | https://bips.dev/174 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki |
二、放在哪一族
钱包协作与离线签名族的核心格式文档。在它之前,“造一笔未签名交易、交给多方依次签名”没有统一格式,各家钱包实现互不相通;BIP-174 把这件事标准化,此后多签、硬件钱包与气隙(air-gapped)签名才有了共同语言。
它建立在既有概念之上,并为后续扩展留了登记机制:
BIP-32:分层确定性钱包,PSBT 中的派生路径与主密钥指纹按它定义
BIP-143:SegWit 签名哈希,原文在签名者校验一节中讨论其与 UTXO 提供方式的关系
新字段与新版本须另写 BIP 并登记到本篇配套的类型注册表(type registry),本篇是 PSBT 版本 0 的定义文档。
三、它要解决什么
3.1 多方接力签名缺少共同格式
创建未签名或部分签名的交易、在多个签名者之间传递,原先是实现相关的:用不同钱包软件的人很难把同一笔交易传下去签名、再把签名合并。本篇目标是给出一个标准且可扩展的格式,让不同客户端能传递同一笔待签交易。
3.2 离线签名者拿不到 UTXO
签名需要知道所花费的 UTXO。若签名设备是离线的硬件钱包或气隙钱包,它无法自己查 UTXO 集。本格式把签名所需的全部信息装进交易文件本身,离线签名者不必直连 UTXO 集,也降低被欺骗的风险。
四、规则本身
4.1 总体结构:键值映射
PSBT 是二进制格式,由若干键值映射(map)组成:
<psbt> := <magic> <global-map> <input-map>* <output-map>*
<magic> := 0x70 0x73 0x62 0x74 0xFF
魔术字节是 ASCII 的 psbt 加分隔符 0xFF,刻意让普通交易解析器无法把它当普通交易解析,反之亦然。每张映射由若干键值对组成,以 0x00 字节结尾。键由键长度、键类型与键数据组成,同一映射内键必须唯一,出现重复键的 PSBT 无效。
4.2 三类字段
- 全局字段:未签名交易本身(
PSBT_GLOBAL_UNSIGNED_TX,其中各输入的 scriptSig 与 witness 必须为空、且用不带见证的旧序列化)、全局扩展公钥(xpub,配合 BIP-32 指纹与派生路径)、版本号、专有字段(0xFC)等; - 每输入字段:被花费的 UTXO(非见证 UTXO 给出完整前序交易;见证 UTXO 给出金额与 scriptPubKey)、部分签名(公钥→签名)、sighash 类型、赎回脚本、见证脚本、BIP-32 派生路径、最终 scriptSig/scriptWitness、各类哈希原像等;
- 每输出字段:赎回脚本、见证脚本、BIP-32 派生路径、专有字段等,供签名者核对收款与找零去向。
签名者遇到不认识的键值对,必须在重新序列化时原样透传;任何键或值不符合其类型格式,整个 PSBT 视为无效。
4.3 版本 0
版本 0 是 PSBT 的首个版本:可省略全局版本字段,或将其设为 0;必须包含未签名交易字段,缺失即无效。版本号只是为未来不兼容变更预留的保险,遇到不认识的版本号,解析器应立即退出。
4.4 表示方式
PSBT 可用二进制文件(扩展名 .psbt)传递,也可按 RFC 4648 编为 Base64 字符串传递。
五、谁必须动
原文把处理流程拆成六个角色,同一软件可以兼任多个角色:
创建者(Creator):造出未签名交易并放入 PSBT,同时建好空白的输入与输出映射。
更新者(Updater):补入自己掌握的信息,如某输入的 UTXO、赎回脚本、见证脚本与派生路径。
签名者(Signer):只能使用 PSBT 内提供的 UTXO 产生签名;签非见证输入前须核对非见证 UTXO 的 TXID 与未签名交易一致,签见证输入前须核对脚本哈希关系;签名以“部分签名”键值对加入,不能签就不加。签名者不应再需要 PSBT 之外的信息源。
合并者(Combiner):把多份针对同一笔交易的 PSBT 合并为一份,去重并汇集全部键值对;冲突时可任选其一或拒绝合并。合并者不必理解脚本。
输入定稿者(Input Finalizer):当某输入材料齐全时,构造最终 scriptSig 与 scriptWitness,并清掉该输入中除 UTXO 与不认识字段外的其他数据。
交易提取者(Transaction Extractor):确认全部输入已定稿后,拼出可广播的完整网络序列化交易。
普通持币人:不必手写 PSBT;使用支持 PSBT 的钱包做多签或硬件钱包签名时,文件或 Base64 文本在设备之间传递的就是它。
全节点与矿工、共识层:无改动。PSBT 完全活在链下,最终上链的仍是普通交易。
六、现在算不算数,以及一个常见误读
状态为 Deployed(已部署)。它是版本 0 的格式定义,后续字段与版本按本篇规定另行立项并登记。原文只定义格式与角色,不声称某一款具体钱包的支持情况;某款钱包是否支持 PSBT、以何种方式传递,应查该钱包自身文档,不要由本篇状态推断。
常见误读:
“PSBT 是一种新的交易类型,上链后能看到。”
不对。PSBT 是链下的半成品容器:交易在凑齐签名之前根本不能广播;定稿提取出的仍是普通比特币交易,链上看不到“PSBT 的痕迹”。它解决的是签名之前的协作问题,不是共识或交易格式问题。
七、延伸
- 阅读版:https://bips.dev/174
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
- 相关:BIP-32 分层确定性钱包、BIP-143 SegWit 签名校验
- 仓库总目录:https://github.com/bitcoin/bips
