术语表 /开发者参考
MSG_WITNESS_TX
- MSG_WITNESS_TX 是什么?
- 见证交易请求以 getdata 消息发送,用于通知对等节点返回所指定的交易,并保留其签名数据,而不是将其剥离。
规定于 BIP-144。
以 txid 通过 MSG_WITNESS_TX 请求一笔交易,返回的是附带签名的版本。Bitcoin Core 0.21.0于2021年1月14日发布,加入了 wtxid 中继,并在很大程度上以 MSG_WTX 取代了这种请求,后者改为按见证哈希请求。对于发送比特币的人来说,好处在于:签名被改动不会再使一笔付款从中继中消失。
运作方式
每笔隔离见证交易都有两个标识,而 MSG_WITNESS_TX 之所以存在,是因为必须告知对等节点所请求的是其中哪一个。
txid 是不含见证数据的交易(版本、输入、输出、锁定时间)的双重 SHA-256哈希。wtxid 是对完整序列化数据计算的同一种哈希,其中包括标记字节、标志字节和见证栈。对于完全没有见证数据的交易,两者相等。对于 coinbase 交易,BIP141 将 wtxid 定义为32字节的零,这是一个特例,目的是让见证默克尔根有一个明确的依托。
该请求的代码是0x40000001:交易类型1再加上见证标志0x40000000。若只发送类型1的 getdata,对等节点返回的是剥离了见证数据的字节,这足以看出资金去向,却无法用来核对该笔支出是否经过授权。
这种拆分终结了旧有的延展性问题。在隔离见证之前,第三方可以重新编码签名、改变 txid,使发送方一直在等待一笔在该名称下已不存在的交易。将签名移到 txid 之外就堵住了这一漏洞,而这也使预先签名的闪电网络通道交易可以放心依赖。
BIP339 随后把这一逻辑又推进了一步。在 verack 之前发送 wtxidrelay 消息的对等节点,会使用清单类型5按 wtxid 公布交易,Bitcoin Core 自0.21.0起即已如此。好处体现在拒绝缓存上:某个节点拒绝了一份格式错误的见证数据后,不会再拒绝同一笔交易的正常副本,因为两者的 wtxid 不同。MSG_WITNESS_TX 仍保留给从未协商 wtxid 中继的对等节点,实际上指的是早于该版本的软件。
在哪里会遇到它
要并排看到 txid 和 wtxid,最清楚的地方是 Bitcoin Core 自带的交易 RPC 的输出。
对任何一笔隔离见证支出调用 getrawtransaction 并使用详细输出,会得到 txid 字段和 hash 字段,两者不同。hash 就是 wtxid,这一差异是见证数据在一个看似普通的 JSON 对象中唯一可见的痕迹。区块浏览器按 txid 建立索引,因此核实提币是否到账时,应把 txid 粘贴到搜索框。
在网络层面,getpeerinfo 按类型统计消息,在任何连接良好的节点上,该统计中的交易请求都是混合的:发给较新对等节点的是 MSG_WTX,发给落后节点的是 MSG_WITNESS_TX。
这一切都不需要购买者去配置,它的影响是间接的。当交易所告知提币已广播而您的钱包找不到时,有用的问题是所给的 txid 是否曾进入内存池,而不是对等节点交换了哪种序列化形式。
MSG_WITNESS_TX vs MSG_TX
MSG_TX 指向同一笔交易,但返回的是剥离了全部签名的版本。这是隔离见证之前的节点所能理解的形式,至今仍会发送给从未声明 NODE_WITNESS 的对等节点。这一区别并非表面文章:拿到剥离版本的节点可以确认交易结构,却无法验证交易,因此无法安全地将其放入内存池,也无法将其作为已验证交易继续中继。Bitcoin Core 不会向只支持旧形式的对等节点发送隔离见证交易。