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

BIP-337 压缩交易

提出一套交易压缩序列化,利用字段的有限取值、紧凑整数与公钥恢复,把典型交易压到原大小的一半以下。本 BIP 目前处于草案状态。

一、档案卡

档案卡
编号BIP-337
标题Compressed Transactions
作者Tom Briar <[email protected]>
指定日期2024-02-01
层级API/RPC(接口)
类型Specification(规范类)
状态Draft(草案)
阅读版https://bips.dev/337
官方原文https://github.com/bitcoin/bips/blob/master/bip-0337.mediawiki

二、放在哪一族

交易序列化与接口族。本篇被归在 API/RPC 层,参考实现落成的也是两个新的 RPC 端点,而不是新的共识规则或 P2P 消息:它定义的是一种在软件之间搬运交易时可用的紧凑编码,解压后必须还原出原来那笔逐字节的标准交易。

它与既有交易形态的关系是“编码层”的关系:被压缩的对象仍然是普通的比特币交易,涵盖 P2PK、P2PKH、P2SH、P2WPKH、P2WSH、P2TR 等脚本类型,原文的测试向量就分别给出了 Taproot、P2WPKH、P2SH-P2WPKH 与 P2PKH 交易压缩前后的对照。

原文提到的一个应用背景是:已有一个进行中的 app,用隐写术把数据编码进图片、经各类社交媒体群组传递;配合本压缩方案与 elligator squared 加密,可以构造一种非常安全、私密的交易广播方式。本篇本体只定压缩方案,不规范隐写或广播渠道本身。

三、它要解决什么

典型的比特币交易里有大量“空白与填充”:许多字段实际上只取少数几个可能值中的一个,却都按完整的 32 位或固定长度存放。原文主张,利用这一事实与若干类似手法,可以为约 90% 的比特币交易构造一种编码,使其大小约为原来的 25%–50%。

压缩后的交易序列化大小可降到原交易的一半以下。其中一种手法——压缩交易的输出点(outpoint)——在原文表述中,是一种“可能有损”(potentially lossy)的途径,因此被设为可选路径;但要让压缩交易降到原大小的 70% 以下,压缩输出点又是必要的。

四、规则本身

4.1 四种主要手法

原文列出的四种主要压缩方法是:

  1. 在交易数据之前、以及每个输入与输出之前打包元数据,用元数据决定后续数据结构如何解读;
  2. 把 32 位数值换成变长整数(VarInt)或紧凑整数(CompactSize)编码;
  3. 使用压缩后的签名,并在解压时做公钥恢复;
  4. 把 36 字节的输出点(txid/vout 对)替换为区块高度与索引。

4.2 基本原语

4.3 总体结构与交易元数据

一笔压缩交易依次由:1 字节交易元数据、按元数据决定是否出现的版本/输入计数/输出计数/LockTime(各为 CompactSize 编码)、可选的最低区块高度(VarInt)、全部输入与输出的元数据、输入数据、输出数据组成。

交易元数据这 1 个字节按位拆分:版本占 2 位(CompactSize 标志)、输入计数占 2 位、输出计数占 2 位、LockTime 占 1 位(是否有 LockTime)、最低区块高度占 1 位(是否大于零)。最低区块高度用于压缩输入与 LockTime 的基准。

4.4 输入、输出的元数据与数据

每个输入的元数据包含:签名是否压缩(1 位,仅 P2TR 的密钥路径花费与被包装的 P2SH-P2WPKH 可压缩签名)、签名哈希类型是否标准(1 位,Taproot 的标准值为 0x00,传统/SegWit 为 0x01)、序列号的 CompactSize 标志(2 位,字面值映射为:1 表示 0x00000000,2 表示 0xFFFFFFFE,3 表示 0xFFFFFFFF)、输出点是否压缩(1 位)。

每个输出的元数据是 3 位的脚本类型编码:000 自定义脚本(不压缩)、001 未压缩 P2PK、010 压缩 P2PK、011 P2PKH、100 P2SH、101 P2WPKH、110 P2WSH、111 P2TR。

输入数据部分包括:输出点(压缩时只写“距最低区块高度的偏移”与“该高度下被压平的索引”两个 VarInt,未压缩时写 32 字节 txid 加 CompactSize 编码的 vout)、签名(压缩时为 64 字节签名,P2SH-P2WPKH 还附 20 字节公钥哈希,非标准时附 1 字节哈希类型;未压缩时为带长度前缀的字节流)、以及非标准序列号才出现的 VarInt 序列号。

输出数据部分包括:输出脚本(带长度前缀的字节流)与金额(VarInt)。

4.5 理想交易与预期收益

该方案是为“典型”交易优化的:花费少数几个年龄相近的输入、带一两个输出。原文的表格给出这种交易在各字段上的最高节省量,例如:版本、输入计数、输出计数、LockTime 若满足小取值条件,各可省至多 30 位;序列号取常见值时每个输入可省至多 62 位;压缩输出点时每个输入的 txid 可省 23–31 字节;非自定义脚本的签名每个传统输入可省 40–72 字节;输出脚本每个输出可省 2–5 字节,等等。

4.6 接口与测试向量

参考实现新增两个 RPC 端点:compressrawtransaction 接收十六进制编码的原始交易,返回紧凑的十六进制交易,并附一份警告列表,帮助确认没有出现意料之外的未压缩值;decompressrawtransaction 接收紧凑的十六进制交易,返回解压后的原始交易。参考实现指向原文所列的 Bitcoin Core 合并请求。测试向量部分给出四类交易(Taproot、P2WPKH、P2SH-P2WPKH、P2PKH)各自未压缩与压缩后的完整十六进制串,供实现者对拍。

向后兼容方面,原文明确称没有向后兼容方面的顾虑。

五、谁必须动

普通持币人:通常无感。它是一种可选的编码,只在某个工具或应用选择使用时,才在该环节内出现;链上的交易格式不变。

钱包开发者:若想在存储、传输或特殊广播场景中用压缩编码,需实现编解码器,并注意压缩输出点是可选且可能有损的路径,以及签名压缩只适用于原文列明的输入类型。是否启用、启用哪些路径,由应用自己决定。

全节点与矿工:无事可做。解压还原出的仍是标准交易,验证与打包规则不变;RPC 端点是参考实现给出的接口形态,不是节点必须提供的服务。

共识层:不涉及。本篇不改变交易的合法性定义,不进共识、不进区块。

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

状态为 Draft(草案)。这套压缩序列化仍是提案阶段的规范,草案状态意味着它尚未成为被普遍实现的标准接口;原文除参考实现外没有给出其他实现的采用情况,本页不臆测。

常见误读:

“BIP-337 能把区块或链上交易本身变小一半。”

不对。它压缩的是交易在接口、存储或带外传输环节中的序列化表示,解压必须还原为原始标准交易才能被网络接受;区块大小、链上数据格式与共识规则都没有因此改变。原文的“原大小一半以下”指的是压缩编码与原序列化相比,不是链上足迹打折。

七、延伸

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