协议演进 / BIP/比特币改进提案 / BIP-339
BIP-339
交易公告与索取改用包含见证数据的 wtxid 而非 txid,堵住见证可锻性带来的中继干扰与重复下载。本 BIP 目前处于已部署状态。
一、档案卡
| 编号 | BIP-339 |
|---|---|
| 标题 | WTXID-based transaction relay |
| 作者 | Suhas Daftuar <[email protected]> |
| 指定日期 | 2020-02-03 |
| 层级 | Peer Services(对等服务) |
| 类型 | Specification(规范类) |
| 状态 | Deployed(已部署) |
| 阅读版 | https://bips.dev/339 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki |
二、放在哪一族
对等网络(P2P)协议族,处在交易中继(transaction relay)这条链路上:节点先用 inv 公告“我有这笔交易”,对方再用 getdata 索取。
它建立在隔离见证(SegWit)之上:wtxid 这个概念由 BIP-141 定义——对包含见证数据的完整交易再做一次哈希;带见证的序列化方式见 BIP-144。BIP-339 做的事,是把中继环节引用交易的标识从 txid 换成 wtxid。
同族邻居:BIP-338(同作者,disabletx 消息,管哪些连接不走交易中继);更早的中继优化还有 BIP-152 紧凑区块中继。
三、它要解决什么
历史上,inv 公告交易时用的都是 txid——不包含见证数据的哈希。SegWit 被网络采用之后(BIP-141、BIP-143、BIP-144),这一惯例仍未改变,而问题恰恰出在见证上:
一笔交易的见证可以被改动(malleated)而不改变其 txid。于是节点收到一份见证被改过、因而拒绝接受的交易后,当其他对等节点再公告同一个 txid 时,它通常还是会再下载一遍——因为它没法仅凭 txid 区分“这次是完好版本还是又一份被改过的版本”。
反过来处理也不行:如果节点拒绝一次后就拉黑该 txid、再不下载,第三方就能抢先把一份见证被改坏的无效版本公告给各节点,让大家误以为这个 txid 已经“见过且无效”,从而把正版交易的中继堵死。
症结在于公告标识没有承诺见证内容。改用 wtxid——它把见证也算进哈希——两种版本天然是两个不同的标识,上述两难随之消除。这正是原文 Motivation 的完整逻辑。
四、规则本身
4.1 协商消息 wtxidrelay
- 新增一条名为
wtxidrelay的空消息(pchCommand == “wtxidrelay”); - 实现本 BIP 的节点,协议版本须为 70016 或更高;
- 收到协议版本 ≥ 70016 的对等节点的 version 消息后,必须在发送 verack 之前回送 wtxidrelay;
- verack 之后才收到的 wtxidrelay,必须忽略或视为无效。
只有双方都发过这条消息的连接,才启用基于 wtxid 的中继。
4.2 新的 inv 类型 MSG_WTX
- 新增 inv 类型
MSG_WTX(0x00000005),可用于inv消息与getdata请求,表示所引用的哈希是交易的 wtxid,而不是 txid; - 在
getdata中使用 MSG_WTX 时,还隐含要求:被索取的交易应按 BIP-144 连同见证一起序列化返回。
4.3 启用后的行为
- 收到对方的 wtxidrelay 后,向该对等节点公告交易时必须使用 MSG_WTX 类型;
- 索取对方公告过的交易时,应当(SHOULD)使用 MSG_WTX 的 getdata;
- 但仍可以(MAY)用旧的 MSG_TX 索取交易——原文举的例子:索取一笔对方并未新近公告过的交易,例如刚公告交易的父交易。
4.4 向后兼容与实现
基于 wtxid 的中继只在双方都支持的对等节点之间启用,旧客户端在本改动后仍完全兼容、可互操作。原文给出的实现是 Bitcoin Core 的 PR #18044。
五、谁必须动
普通持币人:无感。交易本身、地址、签名方式都不变。
钱包开发者:无需改动。钱包构造与广播的交易与从前完全一样,变的只是节点之间公告时用的标识。
全节点开发者与节点运营者:实现 wtxidrelay 协商与 MSG_WTX 的公告/索取逻辑,升级后与同样升级的对等节点自动启用;对旧对等节点自动回退 txid 方式。
共识层:不涉及。txid 与 wtxid 的定义早在 BIP-141 就已定下,本 BIP 一个字也没改共识规则,只改中继层引用交易的方式。
六、现在算不算数,以及一个常见误读
状态为 Deployed(已部署)。它是一个已经落地的对等协议约定:支持的节点两两协商启用,不支持的老节点继续按 txid 中继,两套方式在同一网络上长期共存——这正是原文向后兼容一节的设计。
常见误读:
“BIP-339 之后,交易的 ID 换成 wtxid 了。”
不对。交易仍然同时有 txid 与 wtxid 两个哈希,txid 的定义和用途没有变——例如一个输出被哪笔交易花费,靠的仍是 txid 定位。本 BIP 只规定了一件事:在支持它的两个节点之间,公告与索取交易时改报 wtxid。把“中继时怎么称呼这笔交易”和“交易本身的标识体系”混为一谈,就会误以为全网改了 ID。
七、延伸
- 阅读版:https://bips.dev/339
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki
- 相关:BIP-141 隔离见证(共识层,wtxid 定义)、BIP-144 隔离见证(对等服务,带见证序列化)、BIP-338 禁用交易中继消息
- 仓库总目录:https://github.com/bitcoin/bips
