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

BIP-370 PSBT 第 2 版

PSBT 的第 2 版:把交易信息从一笔固定的未签名交易里拆回各输入输出自己的字段,使 PSBT 创建之后仍能增删输入与输出。本 BIP 目前处于已部署状态。

一、档案卡

档案卡
编号BIP-370
标题PSBT Version 2
作者Ava Chow <[email protected]>
指定日期2021-01-14
层级Applications(应用)
类型Specification(规范类)
状态Deployed(已部署)
阅读版https://bips.dev/370
官方原文https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki

二、放在哪一族

PSBT(部分签名比特币交易)家族的版本升级。它定义的对象由 BIP-174 首创:一种在多个钱包、设备与人之间传递“还没签完的交易”的标准格式,让创建、补充信息、签名、合并、广播可以由不同角色分工完成——硬件钱包离线签名、多签各方接力签名,都靠它。

BIP-174:PSBT Version 0,本 BIP 要修订的对象

BIP-370:PSBT Version 2,只新增字段与字段的必备/禁用规则,其余沿用 BIP-174 的通用格式与角色框架

后续多个 BIP 都是往 PSBT 里加字段,例如 BIP-371 的 Taproot 字段、BIP-373 的 MuSig2 字段;BIP-353 也定义过一个按输出的 PSBT 字段(DNSSEC 证明)。这些扩展字段在 v0 与 v2 中的可用版本,分别由各自文档标注。

一个命名注脚:为什么没有 Version 1?原文脚注解释,BIP-174 的 v0 在口语里常被叫作“version 1”,本提案设计阶段又一直被叫作 version 2,为免混乱,干脆跳过 1、直接定为 2。

三、它要解决什么

BIP-174 的 v0 有一个结构性限制:全局区里放着一笔完整的未签名交易(PSBT_GLOBAL_UNSIGNED_TX),交易长什么样在创建 PSBT 的那一刻就焊死了。此后任何角色都不能再往里加输入或输出,也不能删——想凑整、想合并付款、想多方各出一个输入搞协作交易(例如 CoinJoin 式的多方共同构造),v0 都接不住。

还有一个附带的不便:某个输入或输出的信息被劈成两半,一半在它自己的 input-map / output-map 里,另一半(前序交易、金额、脚本等)埋在那笔全局未签名交易里,读取方要到两处拼凑。

BIP-370 的解法很直接:把全局未签名交易整个去掉,交易版本、锁定时间、每个输入花的是哪笔前序输出、每个输出的金额与脚本,全部拆成独立字段,分别放回全局区与各自的输入/输出区。信息归位之后,增删输入输出才成为可能。

四、规则本身

4.1 总原则

PSBTv2 只规定新字段以及字段的包含/排除要求,通用序列化格式与 BIP-174 相同。

4.2 全局字段

4.3 按输入字段

4.4 按输出字段

4.5 锁定时间怎么定、唯一标识怎么算

交易的 nLockTime 由全局回退值与各输入的必需锁定时间共同决定:没有任何输入提要求时,用 PSBT_GLOBAL_FALLBACK_LOCKTIME(缺省 0);有输入提要求时,只能选全体提要求的输入都支持的那一类(时间型或高度型),取该类中的最大值;若两类都有可能(有输入同时给了两类),选高度型——原文给的理由是签名要承诺锁定时间,签名方必须能唯一确定用哪个,而比特币的时间单位本质上是区块高度。

PSBTv2 的唯一标识:用其中的字段拼出一笔未签名交易并计算其 txid。其中 sequence 一律置 0(因为 Updater 与 Combiner 可以改 sequence),锁定时间按上段规则计算。

4.6 角色变化

v2 在 BIP-174 的角色链(Creator、Updater、Signer、Combiner、Input Finalizer、Transaction Extractor)中插入了一个新角色,并改了几个角色的义务:

4.7 与 v0 的兼容

两者共用 BIP-174 的通用格式,v0 的解析器只需增加对新字段的支持即可反序列化 v2。但因版本号不同,v2 与 v0 有意互不兼容——正是为了能名正言顺地去掉全局未签名交易。需要转换时,可以从 v2 字段拼出未签名交易,再据此生成一个 v0 的 PSBT。原文附了大量测试向量,多数是“v0 里混入 v2 字段”或“v2 缺必备字段”一类应判定为无效的样例。

五、谁必须动

普通持币人:无直接感知。PSBT 是钱包与签名设备之间的幕后格式,最终广播出去的仍是普通比特币交易,链上看不出这笔交易曾用 v0 还是 v2 传递。

钱包与签名设备开发者:是主要的动工方——要实现 v2 的字段拆分、计数维护、可修改标志的检查与更新、新角色 Constructor 的流程,以及锁定时间裁决规则。只支持 v0 的软件无法处理 v2 的 PSBT。

多签与协作交易参与方:间接受益方。输入输出可在创建后增删,多方接力构造同一笔交易(各加各的输入、签名方逐个加入)才有了标准格式支撑;同时每位后加入者都必须遵守可修改标志与 SIGHASH_SINGLE 配对约束。

全节点与矿工、共识层:完全不涉及。PSBT 是链下的签名协调格式,不改交易格式,不改共识规则。

六、现在算不算数,以及一个常见误读

状态为 Deployed(已部署):表示该标准已经定稿并进入实际部署使用,是 BIP 状态体系里“已被采用”的档位。它不是共识规则,不存在“激活高度”一说;具体哪些钱包与硬件设备支持 v2,原文没有给出清单,本页不臆测。工程上要注意的是混用问题:v2 与 v0 有意不兼容,传递前要确认链条上每个工具都认 v2,否则应在交界处按原文方法转换回 v0。

常见误读:“PSBT Version 2 是比特币交易的第 2 版,升级了链上交易格式。”不对。PSBT 是交易在签完名之前、在各参与方之间流转的链下文件格式;BIP-370 改的只是这个文件的内部字段组织——把交易信息从一笔焊死的未签名交易里拆开,好让输入输出能后加。最终提取、广播的仍是一笔完全普通的比特币交易,节点与矿工对此毫无感知。

七、延伸

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