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

BIP-322 通用签名消息格式

提出基于比特币脚本的通用签名消息格式:不再局限于 P2PKH 地址,任意脚本控制的币都能签消息、证明收款资格或展示资金控制。本 BIP 目前处于已完成状态。

一、档案卡

档案卡
编号BIP-322
标题Generic Signed Message Format
作者Karl-Johan Alm <[email protected]>、Oliver Gugger <[email protected]>
指定日期2018-09-10
讨论日期2018-03-14
层级Applications(应用)
类型Specification(规范类)
状态Complete(已完成)
依赖文档Requires: BIP-174、BIP-340、BIP-341、BIP-342
阅读版https://bips.dev/322
官方原文https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki

二、放在哪一族

消息签名族。旧的标准做法是“用地址对应的私钥签一段消息”,以证明签者与收款地址的关系;这一做法的正式文档是 BIP-137(用私钥签署消息)。但它只支持 P2PKH 一类地址,SegWit、多签、Taproot 等现代脚本无从下手。

BIP-322 把签名对象从“某个私钥”推广到“某个脚本”:只要能满足脚本,就能签。它的依赖关系写在档案里:Requires BIP-174(PSBT)、BIP-340、BIP-341、BIP-342(Schnorr 签名与 Taproot 一族)。其 full 签名形式在结构上又与 Signet 的挑战—求解模式相通,原文称它与 BIP-325(Signet)所用的挑战类似。

三、它要解决什么

3.1 旧格式只认 P2PKH

原文动机开门见山:现行消息签名标准只适用于 P2PKH(以 1 开头)的收款地址。本 BIP 提议用一种基于比特币脚本的方法把标准扩展、普遍化,使任何脚本控制的币原则上都能被签——同时为便于与既有签名硬件互操作,还定义一种形似比特币交易的消息签名格式(其中含有一个无效输入,因此不可能在任何真实网络上被花费)。

3.2 旧签名并不真正证明知道私钥

原文指出的第二个缺陷在密码学层面:现行消息签名格式使用 ECDSA 签名,而这类签名并不承诺公钥,因而并不真正证明签者知道任何秘密密钥——有效的签名可以被第三方微调,变成对某些相关密钥同样有效的签名。

3.3 它能证明什么、不能证明什么

原文罕见地用整段篇幅划界,读时不应跳过:

四、规则本身

4.1 四种签名形态

本 BIP 规定三种签名格式,另加一个资金证明变体。签名者必须在签名前加上所用变体的前缀;为兼容定稿之前的实现,验签者在无前缀时可以假定其为 simple 变体。

4.2 两笔虚拟交易:to_spend 与 to_sign

Full 形式的核心是构造两笔虚拟交易:

如此设计的效果是:验证“签名”,就是验证一笔假交易能否满足真实脚本——脚本解释器怎么验真实花费,就怎么验消息签名。因此任意脚本(包括多签与 Taproot 脚本路径)天然被覆盖。原文要求:除 legacy 外,所有形态的这两笔交易都必须能通过全部共识检查,唯一例外是那个全零前序输出本就不存在。

4.3 资金证明变体的附加规则

资金证明在 full 形式上再进一步:签名者除对单个地址的脚本签消息外,还证明对一任意自选 UTXO 集合的控制。做法是把想展示的 UTXO 全部作为 to_sign 的附加输入,并按“真的在花费它们”那样填好见证与 scriptSig,同时为每个附加输入设置对应的(Non-)Witness UTXO 字段(同一交易的多个输出可作优化省略)。原文划界:这份清单不声称完整(不表示“该地址的全部 UTXO 就是这些”),也不声称未花费(验签者须自行查区块链);验资金者因此需要访问当前 UTXO 集,离线验签者只能证明附加输入见证栈的密码学有效性。

4.4 验证流程与结果

验签者拿到地址、签名与消息后,输出三种状态之一:带时间锁但其余有效时报“在时间 T 有效、年龄 S”;无法检查脚本时报“不确定”(inconclusive);任何检查失败则报“无效”(invalid)。流程概要是:由消息与地址算出 to_spend;把签名解码为 to_sign;若为完整交易或 PSBT,逐项确认各字段与规范一致(尤其第一输入须花费 to_spend 的输出、输出恰好一个且合乎规定);最后确认两笔交易合起来满足全部共识规则。

原文另设有基于 PSBT 的签名流程,分 creator、signer、finalizer 三种角色构造与签署,与 BIP-174 的 PSBT 工作流衔接。

五、谁必须动

普通持币人:当交易所、服务商或交易对手要求“签个消息证明地址是你的”时,由钱包代为生成 BIP-322 签名即可;需要理解的是原文的划界——这种签名证明的是“能控制发往该地址的资金”,不是资金所有权的法律凭证,更不证明某笔历史交易出自你手。

钱包开发者:这是主要行动方。需实现 simple 与 full 两种新格式(前缀、两笔虚拟交易的构造、带标签的消息哈希),处理各类脚本类型的见证栈;支持资金证明的,还要实现 PSBT 变体与附加输入的 UTXO 字段规则。验签一侧须实现三态输出,不得把“不确定”当成“有效”。

硬件签名设备:原文的设计目标之一就是与既有签名硬件易于互操作:签名对象被做成交易形态,硬件可以按近似真实交易的方式呈现与签署;实现时要留意 to_sign 中的无效前序输出,确保设备不会把它误当真实付款。

全节点与矿工:无需改动。签名与验签都发生在链下,借用的只是脚本解释规则本身。

共识层:本 BIP 不修改共识规则。

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

状态为 Complete(已完成):规范文本已经定稿完备,可供钱包实现与互操作。它完成的是“格式标准”,不是共识升级——某个钱包是否支持 BIP-322 签名,取决于该钱包的实现,本站不臆测各产品的采用情况;原文提供的参考实现与测试向量正是为互操作准备的。

常见误读:

“有了 BIP-322 签名,就能证明这笔钱是我的、这笔交易是我发的。”

原文明确否定这种读法:它能表明的只是签者将能够控制发往该收款地址的资金;它不能证明签者发出过某笔先前交易,也不可能在协议层面上“真正证明控制资金”——签名会过时,持钥人也可能替人代签。把 BIP-322 签名当成所有权铁证,是超出规范承诺的推论。

七、延伸

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