协议演进 / BIP/比特币改进提案 / BIP-127
BIP-127
把储备证明做成一笔永远上不了链的交易:第一个输入是承诺信息哈希,其余输入签名证明托管方当时确实控制着这些资金。本 BIP 目前处于已完成状态。
一、档案卡
| 编号 | BIP-127 |
|---|---|
| 标题 | Simple Proof-of-Reserves Transactions |
| 作者 | Steven Roose <[email protected]> |
| 指定日期 | 2019-01-28 |
| 层级 | Applications(应用) |
| 类型 | Specification(规范类) |
| 状态 | Complete(已完成) |
| 阅读版 | https://bips.dev/127 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0127.mediawiki |
二、放在哪一族
托管证明与钱包互操作族。它要标准化的不是一笔真实付款,而是一种“证明我控制着这些币”的凭证构造方式。
它的地基是两个现成标准:普通比特币交易的序列化与验证规则,以及 BIP-174 的 PSBT(部分签名比特币交易)格式。原文还专门为 PSBT 定义了一个扩展字段,好让签名设备能认出“这不是一笔要把钱转走的普通交易”。
它与储备证明的其他研究路线(如隐私更好的 Provisions 一类方案)是并列关系:原文明确说自己只把既成事实做法形式化,不追求那类改进的隐私性质(见第三节)。
三、它要解决什么
3.1 托管方丢币不说,用户无从核验
比特币历史上很早就出现了替用户保管比特币的公司:用户交出币的控制权,换取某种服务。这类公司丢掉用户比特币却不及时公开的案例屡见不鲜。
储备证明(Proof of Reserves)就是让管理大量比特币的公司证明自己控制着相应金额的资金;定期做这种控制权证明,有助于确保没有发生重大损失而无人知晓。
3.2 每家自造一套,用户就得每家重学一遍
“储备证明”这个词并不新,但愿意做的高额托管方并不多。原文给出的原因之一是:每家想做证明的公司都得自创一套构造方法;相应地,用户想核验,就得先弄懂这家的构造。托管方与用户的门槛都被抬高了。
本 BIP 因此只做一件事:把证明的构造定成标准格式,让现有钱包基础设施能直接参与构造,让任何人都能用通用软件按标准流程验证。
3.3 它明确不做什么
原文专门声明:这里的构造有已知短板,主要是隐私性质。学界已有隐私好得多的储备证明机制研究(原文引用了 Provisions 论文),但本 BIP 有意只形式化事实上已经在用的老办法,不引入那些改进。读它时不要期待它解决隐私问题。
四、规则本身
4.1 证明应有的性质
原文先列目标:构造灵活,能支持复杂的钱包基础设施;易于与现有钱包方案(硬件、软件)集成;验证走标准流程,不因发布者不同而不同;证明通过绑定一条信息,防止被他人冒用(把别家的证明抄来当自己的);并且能验证签发者在某个特定区块时控制着资金,不论那之后发生了什么。
4.2 证明格式:一笔故意无效的交易
证明被格式化为一笔普通比特币交易,只做一处小改造,同时起到两个作用:让交易不可花费(资金不冒风险),并把证明与签发者绑定(防抄)。具体构造:
- 第一个输入(承诺输入,commitment input):其在先输出点的 txid 部分,必须设为承诺信息的 SHA-256 哈希,信息前要加上固定前缀 “Proof-of-Reserves: ”(例如信息是 “Some Message”,txid 就是 SHA-256(“Proof-of-Reserves: Some Message”),字符串按 UTF-8 编码);输出索引为 0。
- 其余输入:签名必须承诺(commit)到承诺输入,例如使用 SIGHASH_ALL。也就是说,每一枚被证明的 UTXO 的签名,都把这条承诺信息签了进去。
- 输出:交易必须只有一个输出,金额恰好等于全部输入之和(计算时承诺输入按 0 计),即这笔交易不付矿工费。
由于第一个输入只是一个承诺哈希、并不对应真实 UTXO,这笔交易是无效的,永远不可能被确认上链——无效在这里是设计目的,不是缺陷。
4.3 PSBT 扩展:让签名设备认出这是证明
承诺输入不花费真实 UTXO,不应被签名(scriptSig 与 witness 为空)。这会给签名带来麻烦:硬件钱包通常要求提供每个输入的在先输出或在先交易信息,而承诺输入根本没有这些数据。用假数据绕过或让设备忽略该输入,在多数设备上可行,但用户体验很差:设备不认识储备证明交易,会以为用户在签一笔把全部资金转走的普通交易,确认界面会问类似“确定要把 XXX BTC 发到某地址吗?”
为此,原文给 BIP-174 的 INPUT 映射新增一个字段:
- 类型:储备证明承诺
PSBT_IN_POR_COMMITMENT = 0x09;键只有这 1 字节类型、无附加数据,即{0x09}; - 值:该储备证明的承诺信息字符串,按 UTF-8 编码。
处理带此字段的输入时,钱包必须核对在先输出点的 txid 确实是加前缀的承诺信息的 SHA-256 哈希;必须把该输入金额视为 0,不要求提供在先输出或在先交易;应当向用户展示承诺信息、征得确认后再签其他输入;应当只提供承诺到该输入的签名哈希所产生的签名;应当接受该输入的 scriptSig 为空(视同其 scriptPubKey 为 OP_TRUE)。
4.4 兼容与实现
证明格式建立在比特币交易序列化协议之上,原文称它与任何能解释比特币交易的序列化器始终兼容。原文列出的实现包括 rust-bitcoin 项目中 PSBT 扩展的概念验证分支、一个生成与验证证明的在研工具,以及 BDK(Bitcoin Dev Kit)中的相关实现。
五、谁必须动
托管方(证明签发者):按 4.2 构造证明交易,用被证明 UTXO 的私钥逐一签名,并公布承诺信息与证明,让任何人可验证其在特定区块时的控制权。
普通持币人(验证者):不必信任托管方的自述。用通用验证软件按标准流程核对:第一个输入是否为承诺哈希、其余签名是否承诺到该输入、输出是否为输入总和。自己不托管、不签发的人,日常钱包使用不受影响。
钱包与硬件签名设备开发者:若要支持签发,需实现 4.3 的 PSBT 扩展字段,正确展示承诺信息并处理空 scriptSig 的承诺输入,避免把证明误报成大额转账。
全节点与矿工:不必动。证明交易按设计无效、不会上链,节点照常拒绝它即可。
共识层:无改动。它完全借用既有交易与签名规则。
六、现在算不算数,以及一个常见误读
状态为 Complete(已完成)。按仓库状态解释:这份规范本身已经写完、定稿,可供实现与验证软件依循;它不像软分叉那样需要“激活”,也不表示各托管方都已经在按它发布证明——原文没有给出采用名单,本页也不臆测。它算不算数,取决于具体托管方是否真的按此格式签发、验证者是否真的去验。
常见误读:“托管方发布了 BIP-127 储备证明,就等于证明它没有负债、不会倒闭。”
不对。原文的定位从标题起就是 Simple Proof-of-Reserves:它只证明签发者在某个区块时控制着一批 UTXO 的私钥。它不审计负债、不证明这些币没有同时被多处抵押,更不保证公司经营稳健。把“控制权证明”读成“偿付能力证明”,超出了这份文档自己划定的范围——原文甚至明说,它连隐私方面的已知短板都未处理。
