协议演进 / BIP/比特币改进提案 / BIP-144

BIP-144 隔离见证(对等服务)

为隔离见证定义新的 P2P 消息与序列化格式,让节点能通告、请求和中继见证数据,同时不破坏与旧节点的兼容。本 BIP 目前处于已部署状态。

一、档案卡

档案卡
编号BIP-144
标题Segregated Witness (Peer Services)
作者Eric Lombrozo <[email protected]>, Pieter Wuille <[email protected]>
指定日期2016-01-08
层级Peer Services(对等服务)
类型Specification(规范类)
状态Deployed(已部署)
阅读版https://bips.dev/144
官方原文https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki

二、放在哪一族

隔离见证(SegWit)的网络传输分册。BIP-141 在共识层定义见证结构、并要求未来区块对它作出承诺;本篇补上对等服务层:节点如何对外宣告自己支持见证、如何索要和转发见证数据。

同族关系:

BIP-141:隔离见证(共识层),定义见证本身

BIP-143:v0 见证程序的签名验证规则

BIP-145:getblocktemplate 的隔离见证更新,面向挖矿接口

本篇只管“线上怎么传”,不改变任何一笔交易是否有效。

三、它要解决什么

见证数据被分离出去之后,老的 tx 与 block 消息格式装不下它。若直接改老格式,不支持见证的旧节点会解析失败甚至误判;若另起一套完全平行的消息,又会让交易、区块以及所有处理原始交易的 RPC 都要做双份。

因此需要一套新机制,同时满足三点:

这正是本篇要定义的:新序列化格式、新服务位、新的库存(inv)请求类型。

四、规则本身

4.1 带见证的交易序列化

P2P 协议新增一种交易序列化,在原有字段之间插入两个字节:

见证结构本身是一个栈:先写元素个数(var_int),再逐个写“长度(var_int)+ 字节串”。见证份数不单独编码,由输入个数推定,顺序与输入一一对应;某个输入的见证为空时,编码为一个零字节。

设计上有三个刻意的安排:

若交易见证为空,必须使用旧序列化格式,不得用新格式。

4.2 服务位:NODE_WITNESS

节点在握手时以服务位宣告自己能提供见证:

NODE_WITNESS = (1 << 3)

4.3 两种哈希并存

用于交易默克尔树与输入 outpoint 的交易哈希,永远按不带见证的旧序列化计算——这就是后来通称的 txid。同时新增一种把见证数据算在内的哈希(即 wtxid 的口径):由新序列化计算。见证为空的交易,新旧两种哈希相等。

4.4 中继:新的 inv 类型

getdata 请求新增两种库存类型:

细节规则:

4.5 为什么不另设消息类型

原文明确否决了“另设一套独立消息 + 独立序列化”的方案:那将要求 tx 与 block 消息各做一份,所有处理原始交易的 RPC 也要复制一份;否则就只能靠低效、不确定的猜测来判断该用哪种格式。在原消息内扩展序列化,是成本最低的路径。

五、谁必须动

普通持币人:无感。不需要改钱包,也不需要改收款方式;变化发生在节点之间的线路上。

钱包开发者:直连 P2P 网络的轻钱包需要能解析新序列化、按 txid 请求带见证的交易;通过自家节点或服务商接口同步的钱包通常不受影响。

全节点与矿工:要提供和中继见证数据,必须实现新序列化、设置 NODE_WITNESS 服务位,并响应 MSG_WITNESS_TX / MSG_WITNESS_BLOCK 请求。不升级的节点仍可正常收发无见证数据,只是拿不到见证部分。

共识层:本篇不修改共识规则。交易是否有效由 BIP-141 等共识文档决定;本篇只决定这些数据在网络上如何编码与传递。

六、现在算不算数,以及一个常见误读

状态为 Deployed(已部署)。它随隔离见证一起成为节点网络的实际传输方式:今天节点之间索要带见证的交易与区块,走的就是本篇的序列化与 inv 类型。原文的参考实现指向比特币核心的相应合并请求;各客户端的具体实现进度不在原文范围内,本页不另行断言。

常见误读:

“BIP-144 是隔离见证的激活规则。”

不对。本篇没有激活条件,也不定义见证的共识语义;它只是对等服务层的“运输规范”。激活与有效性看 BIP-141 及其部署安排,签名怎么验看 BIP-143。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。