协议演进 / BIP/比特币改进提案 / BIP-69
BIP-69
规定钱包按字典序排列交易输入与输出:输入按前一笔交易哈希与输出序号,输出按金额与 scriptPubKey,以减少钱包指纹与隐私泄漏。本 BIP 目前处于已完成状态。
一、档案卡
| 编号 | BIP-69 |
|---|---|
| 标题 | Lexicographical Indexing of Transaction Inputs and Outputs |
| 作者 | Kristov Atlas <[email protected]> |
| 指定日期 | 2015-06-12 |
| 层级 | Applications(应用) |
| 类型 | Informational(信息类) |
| 状态 | Complete(已完成) |
| 阅读版 | https://bips.dev/69 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki |
二、放在哪一族
BIP-69 是钱包隐私族的一份信息类文档。它不改协议、不改交易有效性,只统一钱包在组交易时的一个细节:输入和输出的排列顺序。
它与 BIP-67 气质相近:都是钱包层面的确定性约定,都不靠网络强制,靠的是“大家排得一样,个体才不显眼”。原文在动机与实现上多次提到多人共同构造的交易(如 CoinJoin)——排序规则只用公开的链上信息,多方场景同样适用;原文的实现一节列有 Electrum、BitcoinJS、Blockchain.info、Btcsuite 等采用方。
三、它要解决什么
在 BIP-69 之前,钱包客户端如何排列交易输入与输出没有任何标准。各钱包自行其事,结果是向被动的链上观察者泄漏用户信息:
- 有的钱包按地址被导入或生成的先后排列输入,暴露钱包内部历史;
- 许多钱包把支付输出放前面、找零输出放后面,等于直接告诉观察者哪笔是付款、哪笔是找零,发送方与接收方的财务状况都被泄漏;
- 原文引的一个实例:有研究者侦测到 Bitstamp 在构造交易所交易时泄漏了信息,使交易者之间可能互相刺探。
一个自然的对策是随机排序——输入输出的顺序本来不影响交易功能。但原文指出随机排序有个审计难题:无法从代码或运行时分析证明排序真的随机,尤其软件闭源时。恶意的软件开发者甚至可以把顺序当作侧信道:把主私钥的比特编码进输入输出次序里,看链就能最终偷走用户全部资金。非确定性的方法不可重复,因而难以审计。
各钱包排序习惯不同还带来另一重问题:可预测的怪癖构成各钱包或服务独有的“指纹”,隐私攻击者仅靠被动观察链上数据就能分辨交易出自哪家钱包。
结论是把排序做成确定性的:同一笔交易,正确次序应当是显而易见的;规则只依赖全节点与 SPV 节点都已下载、且链上人人可见的公开信息,不触碰任何机密数据。
四、规则本身
4.1 适用范围
适用于一切“输入输出顺序不影响功能”的交易。目前实际所指的是使用 SIGHASH_ALL 签名哈希类型的交易——签名承诺的正是输入输出的确切顺序。使用 SIGHASH_ANYONECANPAY 和 / 或 SIGHASH_NONE 的交易虽含未被签名覆盖的输入或输出,合规软件仍应输出已按字典序排好的交易,哪怕之后可能被他人改动。将来若有新的签名哈希类型,合规软件应类推适用字典序原则。
确实要求特定顺序的协议(如因使用 SIGHASH_SINGLE)不在本 BIP 范围内,但原文建议它们参照本 BIP 的目标自行适配。
所有比较都不需要常数时间,因为处理的信息不是秘密。
4.2 输入的排序
排序键只用两样:前一笔交易的哈希与该交易内的输出序号——交易哈希在链上以极高概率唯一(coinbase 交易的唯一性由 BIP-30 保证),同一交易内输出序号也唯一,足够定序。
- 先比交易哈希:前一笔交易哈希按(反转字节序后的)形式升序、字典序排列;出于效率,先比哈希是因为不同交易的输出序号常相同,而哈希的每个字节都近似随机变量;
- 哈希相同,再比输出序号:按整数值升序;
- 两者都相同,两个输入视为相等。
原文还指出:交易可塑性不会破坏这一过程的正确性——哪怕钱包用未确认 UTXO 做输入、攻击者改了前一笔交易在链上的哈希记录,钱包仍是按它写进输入数据的那个(已失效的)哈希在正确排序。
4.3 输出的排序
输出由金额与 scriptPubKey 两样定义:
- 先比金额:金额按 64 位无符号整数升序排列。先比金额也是出于效率——金额只有 8 字节,比标准 P2PKH 的 scriptPubKey(25 字节)信息量少;
- 金额相同,再比 scriptPubKey:按字节数组字典序升序;
- 两者都相同,两个输出视为相等。
原文附有两笔真实交易的完整输入输出序列作为示例,可用来核对实现。
五、谁必须动
普通持币人:不必做任何事。若钱包遵循本规范,其交易的排列不再自带可识别的钱包习惯,隐私收益自动获得。
钱包开发者:这是主要受众——组交易时按 4.2、4.3 的两级键排序输入与输出;排序口径只用链上公开数据,不得掺入本地才有的信息。
全节点与矿工:不必动。节点验证交易不看排列是否合规,矿工打包也不受此约束。
共识层:完全不涉及。本规范是信息类文档,提出的是钱包行为约定,不是有效性规则。
六、现在算不算数,以及一个常见误读
状态为 Complete(已完成),类型为 Informational(信息类)。它的“算数”方式是被钱包采用:原文列出的实现已把字典序排序做进组交易逻辑。没有采用的节点或钱包不会因此使任何交易无效。
常见误读:
“按 BIP-69 排过序的交易是‘合规交易’,没排的会被网络区别对待。”
不对。排序不影响交易功能,也不进入任何共识或转发规则;它只决定这笔交易在链上“看起来像谁做的”。不排序的代价是隐私——观察者更容易从次序习惯里认出钱包、分辨找零——而不是有效性。
七、延伸
- 阅读版:https://bips.dev/69
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki
- 相关:BIP-67 同为钱包层确定性约定、BIP-30 coinbase 交易哈希唯一性
- 仓库总目录:https://github.com/bitcoin/bips
