2017 年 8 月隔离见证在比特币主网激活,很多人把它理解成一次单纯的共识规则变更,其实它落地时还带来了另一件不那么起眼、却同样必不可少的东西:一套节点之间传递交易和区块时「怎么把见证数据带上路」的新报文格式。共识规则(BIP-141)规定的是见证要从交易身份计算中剥离、要承诺进区块头;而网络里两台节点之间怎么交换这些被剥离出来的字节,则是 BIP-144 回答的问题。它由 Eric Lombrozo 和 Pieter Wuille 起草,2016 年 1 月立项,随隔离见证一起部署。
BIP-144 的核心是给 tx 消息增加一种新的序列化格式。旧格式是「版本、输入表、输出表、锁时间」四段;新格式在版本字段后面插入两个固定字节:一个叫 marker,必须为零;另一个叫 flag,必须非零;然后在输出表之后、锁时间之前,追加一段与输入一一对应的见证堆栈。一个关键的巧思在于 marker 字节:旧解析器读到版本后面出现零字节时,会把它当成输入数量的 varint——零个输入、然后是一个输出,交易要么解析失败要么明显不合法,绝不会被误当成一笔正常的旧格式交易接受。这就是为什么新格式可以放心在存量网络上广播,而不会因为「旧节点看懂了但理解错了」引发混乱。
规范里有几条容易被忽略但很重要的规则。第一,如果一笔交易根本没有见证(比如纯旧式脚本交易),发送方必须使用旧格式,不许画蛇添足地加两个节字节。第二,见证的数量不单独编码,由输入个数隐含决定:每个输入对应一叠字节数组,先写个数再逐项写长度和内容,空见证就是一个零字节。第三,节点之间通过服务位宣告自己支持隔离见证中继,只有双方都支持时才发送带见证的格式;向不支持的邻居转发时,节点会把见证剥掉再发旧格式,这就是所谓的「降级转发」,让未升级节点也能继续验证不含见证语义的部分。
为什么要用「同一条 tx 消息里塞两种格式」,而不是干脆新增一条独立的 wtx 消息?BIP-144 在理由部分直接回答了:独立消息意味着区块也要另造一条 wblock,所有处理原始交易的 RPC 要么翻倍实现、要么靠猜来决定用户给的十六进制是哪种格式,既低效又容易出非确定性行为。把分辨问题交给「marker 字节在不在」,解析器一次就能判定,工程代价最小。同理,规范解释了为什么标记用两个字节而不是一个零字节:单个零字节会让「零输入加一个输出」这种真实存在的边缘交易(测试里就常构造)被误读成新格式。
对普通用户来说,这套机制留下的最直观遗产是:一笔交易的「身份证」和「说明书」分开了。交易 ID 只算不含见证的部分,所以同一笔钱的 txid 在所有节点上看起来一致,而见证内容另有一个 wtxid 体系供中继层去重和排序。后续不少提案(比如按 wtxid 建内存池索引、按见证重量计费)都建立在这层传输格式之上。可以说 BIP-141 决定了隔离见证「是什么」,BIP-144 决定了它「怎么流动」,少了后者,前者只存在于纸面。
快速问答
问:我怎么判断一笔原始交易是哪种格式? 答:看版本字段之后的字节。如果下一个字节是零且再下一个非零,就是带见证的新格式;否则是旧格式。钱包和浏览器导出的 raw hex 里这 2 个字节一眼可辨。
问:老节点会拒绝带见证的交易吗? 答:不支持的新格式交易从升级节点降级转发后就是纯旧格式,老节点照常验证和打包,只是看不到见证字节本身。这正是设计的目的:兼容不是靠老节点升级,而是靠新节点主动降级。
风险提示:本文讲的是协议传输机制,不涉及任何资产价值判断;使用钱包或节点软件时请以当期版本行为为准。

发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。