分离见证钱包开发指南
概述
本文档的大部分内容可以在与隔离见证相关的 BIP 中找到,包括 BIP141、BIP143、BIP144 和 BIP145。请将此作为参考其他相关文档的第一要点,以及关于应该做什么和不应该做什么的清单。
基本的隔离见证支持
为了被视为基本级别的隔离见证兼容,钱包**必须**实现本节中的所有功能。
发送到 P2SH
- 隔离见证兼容钱包**必须**支持支付至脚本哈希 (BIP16) 及其地址格式 (BIP13)。
- 为了进行支付,钱包必须能够正确地将给定的 P2SH 地址转换为
scriptPubKey
并创建交易。 - 为了接收支付,钱包必须能够基于 P2WPKH 脚本(后文定义)创建 P2SH 地址,并能够识别对此类地址的支付。
- 即使钱包仅接受单签名支付,这也是一项强制性要求。
创建 P2SH-P2WPKH 地址
- P2SH-P2WPKH 地址可与比特币最初的单签名 P2PKH 地址(以 1 为前缀的地址)相比较。
- 与任何其他 P2SH 地址一样,P2SH-P2WPKH 地址以 3 为前缀。
- 在 P2SH-P2WPKH UTXO 被花费并且
redeemScript
被公开之前,P2SH-P2WPKH 地址与非隔离见证 P2SH 地址(例如非隔离见证多签名地址)无法区分。 - 仅当使用 1 个公钥接收支付(如 P2PKH)时,应使用 P2SH-P2WPKH 地址。
- P2SH-P2WPKH 使用与 P2PKH 相同的公钥格式,但有一个非常重要的例外:P2SH-P2WPKH 中使用的公钥**必须**是压缩的,即大小为 33 字节,并以
0x02
或0x03
开头。使用任何其他格式(例如未压缩的公钥)可能会导致不可挽回的资金损失。 - 创建 P2SH-P2WPKH 地址
- 计算公钥的 SHA256 的 RIPEMD160(
keyhash
)。尽管keyhash
公式与 P2PKH 相同,但应避免重复使用keyhash
,以提高隐私性并防止意外使用未压缩密钥。 - P2SH
redeemScript
始终为 22 字节。它以OP_0
开头,后跟keyhash
的规范推送(即0x0014{20-byte keyhash}
)。 - 与任何其他 P2SH 一样,
scriptPubKey
为OP_HASH160 hash160(redeemScript) OP_EQUAL
,地址为相应的前缀为 3 的 P2SH 地址。
- 计算公钥的 SHA256 的 RIPEMD160(
交易序列化
- 隔离见证兼容钱包**必须**支持原始交易格式,如
nVersion|txins|txouts|nLockTime
。 - 隔离见证兼容钱包**必须**还支持新的序列化格式,如
nVersion|marker|flag|txins|txouts|witness|nLockTime
。nVersion
、txins
、txouts
和nLockTime
的格式与原始格式相同。marker
**必须**为0x00
。flag
**必须**为0x01
。witness
是交易所有见证数据的序列化。- 每个 txin 都与一个见证字段相关联。因此,没有关于见证字段数量的指示,因为它由
txins
的数量隐含。 - 每个见证字段以
compactSize
整数 开头,以指示相应txin
的堆栈项数量。如果存在,则后跟相应txin
的见证堆栈项。 - 每个见证堆栈项以
compactSize
整数开头,以指示项的字节数。 - 如果
txin
与任何见证数据无关,则其相应的见证字段为精确的0x00
,表示见证堆栈项的数量为零。
- 每个 txin 都与一个见证字段相关联。因此,没有关于见证字段数量的指示,因为它由
- 如果交易中的所有
txins
均与任何见证数据无关,则**必须**使用原始交易格式序列化交易,不包括marker
、flag
和witness
。例如,如果没有任何txins
来自隔离见证 UTXO,则**必须**使用原始交易格式进行序列化。(例外:创世区块交易) - 交易序列化的示例可以在 BIP143 的示例部分找到。钱包开发人员可以使用这些示例来测试他们的实现是否正确地解析新的序列化格式。
交易 ID
- 在隔离见证下,每个交易将有两个 ID。
txid
的定义保持不变:原始序列化格式的双 SHA256。- 定义了一个新的
wtxid
,它是包含见证数据的新的序列化格式的双 SHA256。 - 如果交易没有任何见证数据,则其
wtxid
与txid
相同。 txid
仍然是交易的主要标识符。- 在引用先前输出时,**必须**在
txin
中使用它。 - 如果钱包或服务当前使用
txid
来识别交易,则预计它将在隔离见证中继续使用此功能。
- 在引用先前输出时,**必须**在
P2SH-P2WPKH 的签名生成和验证
- 对于非隔离见证 UTXO 的花费,签名生成算法保持不变。
- 对于 P2SH-P2WPKH 的花费
scriptSig
**仅**可以包含redeemScript
的推送。- 相应的见证字段**必须**正好包含 2 个项目,一个签名后跟公钥。
- BIP143 中描述了一种用于隔离见证脚本的新签名生成算法。开发人员应仔细遵循说明,并利用 BIP143 中的 P2SH-P2WPKH 示例来确保他们能够重现
sighash
。 - BIP143 签名生成算法涵盖了所花费的输入的值,这简化了断网轻量级钱包和硬件钱包的设计。
- 请注意,对于 P2SH-P2WPKH,
scriptCode
始终为 26 字节,包括前导大小字节,如0x1976a914{20-byte keyhash}88ac
,而不是redeemScript
或scriptPubKey
。 - 示例
网络服务(可选)
- 如果钱包要通过点对点网络发送和接收交易,则需要网络服务。
- 支持隔离见证的节点将通过服务位广告它们可以提供见证:
NODE_WITNESS = (1 << 3)
。 - 没有任何见证数据的交易(因此以原始格式序列化)可以发送到有或没有
NODE_WITNESS
支持的节点。 - 花费隔离见证 UTXO 的交易(因此以新格式序列化)**仅**可以发送到具有
NODE_WITNESS
支持的节点。 - 花费隔离见证 UTXO 但见证数据被剥离的交易(因此以原始格式序列化)可以发送到没有
NODE_WITNESS
支持的节点。但是,此类交易在隔离见证激活后无效,并且不会被包含在区块中。 - 网络服务的详细信息可以在 BIP144 中找到。
用户隐私
- 在隔离见证交易变得普遍之前,这种交易类型可能会使比特币跟踪更容易。
- 使用 P2SH-P2WPKH 作为默认找零输出也可能对隐私产生影响。
交易费用估算
- 代替交易大小,定义了一个新的指标,称为“虚拟大小”(
vsize
)。 - 交易的
vsize
等于原始序列化大小的 3 倍加上新序列化大小,将结果除以 4 并向上取整到下一个整数。例如,如果交易在新序列化下为 200 字节,并且在删除marker
、flag
和witness
后变为 99 字节,则vsize
为 (99 * 3 + 200) / 4 = 125(向上取整)。 - 非隔离见证交易的
vsize
只是其大小。 - 应通过将
vsize
与其他交易进行比较来估算交易费用,而不是大小。 - 开发人员应注意不要在费用估算中犯 4 倍的错误。
激活
- 从区块高度 481824 开始,所有隔离见证就绪节点开始强制执行新的隔离见证共识规则。
向后兼容性
- 发送和接收传统 P2PKH 支付(以 1 为前缀的地址)应继续得到支持。
复杂脚本支持
如果钱包支持除单签名之外的其他脚本类型(例如多签名),则必须满足除基本要求之外的其他要求。
创建 P2SH-P2WSH 地址
- P2SH-P2WSH 地址可与比特币最初的 P2SH 地址相比较,后者允许使用固定大小的地址表示任意复杂的脚本。
- 与任何其他 P2SH 和 P2SH-P2WPKH 地址一样,P2SH-P2WSH 地址以 3 为前缀。在 UTXO 被花费之前,它们是无法区分的。
- 创建 P2SH-P2WSH 地址
- 定义一个脚本,称为(
witnessScript
)。 - 计算
witnessScript
的 SHA256(scripthash
)。请注意,使用的是单个 SHA256,而不是双 SHA256 或 RIPEMD160(SHA256)。 - P2SH
redeemScript
始终为 34 字节。它以OP_0
开头,后跟scripthash
的规范推送(即0x0020{32-byte scripthash}
)。 - 与任何其他 P2SH 一样,
scriptPubKey
为OP_HASH160 hash160(redeemScript) OP_EQUAL
,地址为相应的前缀为 3 的 P2SH 地址。
- 定义一个脚本,称为(
- 脚本限制
- 脚本评估不得失败,并且**必须**在评估后留下一个且仅一个 TRUE 堆栈项。否则,评估将失败。
- P2SH-P2WSH 脚本中的任何公钥**必须**是压缩密钥,否则资金可能会永久丢失。
- 如果使用 OP_IF 或 OP_NOTIF,则其参数**必须**为空向量(对于 false)或
0x01
(对于 true)。使用其他值可能会导致永久资金损失。(BIP 草案) - 如果 OP_CHECKSIG 或 OP_CHECKMULTISIG 返回失败,则所有签名**必须**为空向量。否则,资金可能会永久丢失。(BIP146)
witnessScript
的默认策略限制为 3600 字节。除了witnessScript
之外,最多可以有 100 个见证堆栈项,每个项最多 80 字节。超过这些限制的交易可能不会被转发或包含在区块中。- 许多原始脚本共识限制(例如 10000 字节脚本大小、201
nOpCount
)仍然适用于 P2SH-P2WSH。 - P2SH 的 520 字节脚本大小限制不适用于 P2SH-P2WSH。它被 3600 字节策略限制和 10000 字节共识限制取代。
P2SH-P2WSH 的签名生成和验证
- 对于 P2SH-P2WSH 的花费
scriptSig
**仅**可以包含redeemScript
的推送。- 相应见证字段的最后一个见证项**必须**是
witnessScript
。 - 应用新的 BIP143 签名生成算法。
- 如果不使用任何 OP_CODESEPARATOR,则
scriptCode
为witnessScript
前面加上一个表示witnessScript
大小的compactSize
整数。例如,如果脚本是 OP_1(0x51
),则序列化的scriptCode
为(0x0151
) - 对于任何包含 OP_CODESEPARATOR 的不常见脚本,请参阅 BIP143 以了解其确切语义
- 如果不使用任何 OP_CODESEPARATOR,则
witnessScript
之前的任何见证栈项都用作脚本评估的输入栈。输入栈不会被解释为脚本。例如,无需使用0x4c
(OP_PUSHDATA1)来“推送”大型项。- 要验证签名生成和栈序列化的正确性,请始终根据 BIP143 中的示例进行测试
- 示例
Segwit 原生地址(可选)
以下功能对于初始 SegWit 支持不是必需的。
原生支付至见证公钥哈希 (P2WPKH)
- 原生 P2WPKH 是一个 22 字节的
scriptPubKey
。它以OP_0
开头,后跟keyhash
的规范推送(即0x0014{20-字节 keyhash}
) - 与 P2SH-P2WPKH 相同,
keyhash
是压缩公钥的 RIPEMD160(SHA256)。 - 花费原生 P2WPKH 时,
scriptSig
必须为空,见证栈格式和签名生成规则与 P2SH-P2WPKH 相同(包括使用压缩公钥的要求) - 示例
原生支付至见证脚本哈希 (P2WSH)
- 原生 P2WSH 是一个 34 字节的
scriptPubKey
。它以OP_0
开头,后跟scripthash
的规范推送(即0x0020{32-字节 scripthash}
) - 与 P2SH-P2WSH 相同,
scripthash
是witnessScript
的 SHA256。 - 花费原生 P2WSH 时,
scriptSig
必须为空,见证栈格式和签名生成规则与 P2SH-P2WSH 相同(包括使用压缩公钥的要求) - 示例
为什么以及如何使用原生 (Bech32) P2WPKH 和 P2WSH?
- BIP173 提出了一种针对原生 P2WPKH 和 P2WSH 地址的带校验和的 Base32 格式(Bech32)。
- Bitcoin Core v0.16.0 中包含了对 Bech32 地址的支持。
- 与 P2SH 版本相比,原生版本的交易
vsize
在大多数情况下更小,因此可能需要更少的费用。 - 原生 P2WPKH 和 P2WSH 可与原始
scriptPubKey
协议一起使用,例如支付协议 (BIP70)。但是,这可能会影响付款人和收款人的隐私(见下文)。 - 原生 P2WPKH 和 P2WSH 可用作默认找零地址,但这可能会允许其他人轻松识别找零(见下文)。
- 在原生 P2WPKH 和 P2WSH 广泛使用之前,这些地址类型可能会引起用户的隐私问题。