本文件的大部分内容可以在与隔离认证相关的BIP中找到,包括BIP141,BIP143,BIP144和BIP145。请将此视为阅读其他相关文件的第一个参考点,并作为那些应该做和那些不应该做的检查清单。
基本的隔离认证支持
钱包必须实现本节中的所有功能,以便在基本级别被视为segwit兼容:
发送到P2SH
- 兼容segwit的钱包必须支持
pay-to-script-hash
(BIP16)及其地址格式(BIP13)。 - 对于付款,钱包必须能够正确地将给定的P2SH地址转换为
scriptPubKey
,并创建一个交易。 - 为了接收付款,钱包必须能够基于P2WPKH脚本(在下文中定义)创建P2SH地址,并且能够识别对这些地址的支付。
- 这是强制性要求,即使钱包仅接受单签名付款。
创建P2SH-P2WPKH地址
- P2SH-P2WPKH地址与比特币的原始单签名P2PKH地址(前缀为1的地址)相当。
- 与任何其他P2SH地址一样,P2SH-P2WPKH地址的前缀为3。
- 在使用P2SH-P2WPKH UTXO并暴露
redeemScript
之前,P2SH-P2WPKH地址与非segwit P2SH地址无法区分(例如非segwit多签名地址)。 - 当只有1个公钥用于接收付款时(如P2PKH),应使用P2SH-P2WPKH地址。
- P2SH-P2WPKH使用与P2PKH相同的公钥格式,但有一个非常重要的例外:P2SH-P2WPKH中使用的公钥必须被压缩,即大小为33字节,并以
0x02
或0x03
开头。使用任何其他格式(如未压缩的公钥)可能会导致不可撤销的资金损失。 创建P2SH-P2WPKH地址:
- 1.计算公钥(
keyhash
)的SHA256的RIPEMD160。尽管keyhash
公式与P2PKH相同,但应避免重用keyhash
以获得更好的隐私并防止意外使用未压缩密钥。 - 2.P2SH
redeemScript
始终为22个字节。它以OP_0
开头,然后是keyhash
的规范推送(如0x0014{20-byte keyhash}
)。 - 3.与其他P2SH相同,
scriptPubKey
是OP_HASH160 hash160(redeemScript)OP_EQUAL
,地址是对应的P2SH地址,前缀为3。
- 1.计算公钥(
交易序列化
- 兼容segwit的钱包必须支持原始的交易格式,如
nVersion|txins|txouts|nLockTime
。 兼容segwit的钱包也必须支持新的序列化格式,如
nVersion|marker|flag|txins|txouts|witness|nLockTime
。-
nVersion
,txins
,txouts
和nLockTime
的格式与原始格式相同。 -
marker
必须是0x00
。 -
flag
必须是0x01
。 witness
是交易的所有见证数据的序列化。- 每个txin都与见证字段相关联。作为结果,没有表示显示证据字段的数量,因为它是由
txins
的数量默认的。 - 每个见证字段以compactSize integer开始,以指示相应txin的堆栈项目数。然后是相应txin的见证堆栈项目数(如果有的话)。
- 每个见证堆栈项都以
compactSize integer
开头,以指示该项的字节数。 - 如果
txin
未与任何见证数据相关联,则其对应的见证字段精确为0x00
,表示见证堆栈项的数量为零。
- 每个txin都与见证字段相关联。作为结果,没有表示显示证据字段的数量,因为它是由
-
- 如果交易中的所有
txins
都没有与任何见证数据相关联,则交易必须以原始交易格式序列化,不包括marker
,flag
,witness
。例如,如果没有txins
来自segwit UTXO,它必须以原始交易格式序列化。(coinbase交易例外) - 可以在BIP143的示例部分找到交易序列化的示例。钱包开发人员可以使用这些示例来测试他们的实现是否正确解析了新的序列化格式。
交易ID
- 在segwit下,每个交易将有2个ID。
-
txid
的定义保持不变:原始序列化格式的double SHA256。 - 定义了一个新的
wtxid
,它是具有见证数据的新序列化格式的double SHA256。 - 如果交易没有任何见证数据,则其
wtxid
与txid
相同。 txid
仍然是交易的主要标识符:- 当引用先前的输出时,它必须在
txin
中使用。 - 如果钱包或服务当前正在使用
txid
来识别交易,则预示着它将继续使用segwit。
- 当引用先前的输出时,它必须在
P2SH-P2WPKH的签名生成和验证
- 对于非segwit UTXO的消费,签名生成算法不变。
对于P2SH-P2WPKH的消费:
–scriptSig
必须只包含一个redeemScript
。- 相应的见证字段必须包含2个项目,签名后跟公钥。
- BIP143(见文末)中描述了一种用于segwit脚本的新签名生成算法。开发人员应仔细遵循说明,并使用BIP143中的P2SH-P2WPKH示例,以确保它们能够重现
sighash
。 - BIP143签名生成算法涵盖了所花费的输入值,简化了air-gapped轻量钱包和硬件钱包的设计。
- 请注意,对于P2SH-P2WPKH,
scriptCode
总是26个字节,包括前导大小字节,如0x1976a914{20-byte keyhash}88ac
,不是redeemScript
,也不是scriptPubKey
。 - 示例。
网络服务(可选)
- 如果钱包通过对等网络发送和接收交易,则需要网络服务。
- 支持Segwit的节点将表示他们可以通过服务位提供见证:
NODE_WITNESS=(1<<3)
。 - 没有任何见证数据的交易(因此以原始格式序列化)可以发送到有或没有
NODE_WITNESS
支持的节点。 - 花费segwit UTXO(因此以新格式序列化)的交易必须仅发送到具有
NODE_WITNESS
支持的节点。 - 花费segwit UTXO但剥离见证数据(因此以原始格式序列化)的交易可以发送到没有NODE_WITNESS支持的节点。但是,这些交易在激活segwit后无效,并且在块中不会被接受。
- 有关网络服务的详细信息,请参阅BIP144(见文末)。
用户隐私
- 在segwit交易很普遍之前,这种交易类型可以使比特币跟踪更容易。
- 使用P2SH-P2WPKH作为默认变化时的输出也可能会对隐私产生影响。
交易费用估算
- 替代交易大小,定义了一个新的度量,称为“virtual size”(
vsize
)。 - 交易的
vsize
等于原始序列化大小的3倍,加上新格式序列化的大小,将结果除以4并向上舍入到下一个整数。例如,如果一个交易是200字节的新格式序列化,并且变为99字节,删除了marker
,flag
,witness
,则vsize
为(99*3+200)/4=125并向上舍入。 - 非segwit交易的
vsize
只是它本身的大小。 - 交易费应通过比较
vsize
与其他交易而不是大小来估算。 - 开发人员应注意不要在费用估算中犯off-by-4-times错误。
激活
- 从块高度481824开始,所有SegWit就绪节点都开始执行新的SegWit共识规则。
向后兼容性
- 应继续支持发送和接收传统的P2PKH支付(前缀为1的地址)。
复杂的脚本支持
如果钱包支持除单一签名之外的脚本类型,例如多重签名,则必须满足以下基本要求:
创建P2SH-P2WSH地址
- P2SH-P2WSH地址与比特币的原始P2SH地址相当,后者允许表示具有固定大小地址的任意复杂脚本。
- 与任何其他P2SH和P2SH-P2WPKH地址一样,P2SH-P2WSH地址具有前缀3.在UTXO用完之前,它们无法区分。
要创建P2SH-P2WSH地址:
- 1.定义一个名为
witnessScript
的脚本。 - 2.计算
witnessScript
(scripthash
)的SHA256。请注意使用单个SHA256,而不是双SHA256和RIPEMD160(SHA256)。 - 3.P2SH
redeemScript
总是34个字节。它以OP_0
开头,然后是scripthash
的规范推送(即0x0020{32-byte scripthash}
)。 - 4.与任何其他P2SH相同,
scriptPubKey
是OP_HASH160 hash160(redeemScript) OP_EQUAL
,地址是对应的P2SH地址,前缀为3。
- 1.定义一个名为
对脚本的限制
- 脚本评测不能失败,并且必须在评测后留下一个且只有一个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
,前面是一个compactSize integer
,用于witnessScript
的大小。例如,如果脚本是OP_1
(0x51
),则序列化的scriptCode
是(0x0151
)。 - 对于包含
OP_CODESEPARATOR
的任何异常脚本,请参阅BIP143以获取确切的语义。
- 在不使用任何
- 在
witnessScript
之前的任何见证堆栈项目都用作脚本评测的输入堆栈。输入堆栈不会被解释为脚本。例如,不需要使用0x4c
(OP_PUSHDATA1)来“push”大项。 - 要验证签名生成和堆栈序列化的正确性,请始终根据BIP143中的示例进行测试。
- 示例。
Segwit本机地址(可选)
初始segwit支持不需要以下功能。
本地Pay-to-Witness-Public-Key-Hash(P2WPKH)
- Native P2WPKH是一个22字节的
scriptPubKey
。它以OP_0
开头,然后是keyhash
的规范推送(即0x0014{20-byte keyhash}
)。 - 与P2SH-P2WPKH相同,
keyhash
是压缩公钥的RIPEMD160(SHA256)。 - 当使用原生P2WPKH时,
scriptSig
必须为空,见证堆栈格式和签名生成规则与P2SH-P2WPKH相同(包括使用压缩公钥的要求)。 - 示例。
本地Pay-to-Witness-Script-Hash(P2WSH)
- 原生P2WSH是一个34字节的
scriptPubKey
。它以OP_0
开头,然后是scripthash
的规范推送(即0x0020{32-byte scripthash}
)。 - 与P2SH-P2WSH相同,
scripthash
是witnessScript
的SHA256。 - 当使用原生P2WSH时,
scriptSig
必须为空,见证堆栈格式和签名生成规则与P2SH-P2WSH相同(包括使用压缩公钥的要求)。 - 示例。
为什么以及如何使用Native(Bech32)P2WPKH和P2WSH?
- BIP173为本机P2WPKH和P2WSH地址提出校验和base32格式(Bech32)。
- 比特币核心v0.16.0中包含对Bech32地址的支持。
- 与P2SH版本相比,在大多数情况下,本机版本的交易
vsize
较小,因此可能需要较少的费用。 - 原生P2WPKH和P2WSH可以与原始
scriptPubKey
协议一起使用,例如支付协议(BIP70)。但是,它可能会影响付款人和收件人的隐私(见下文)。 - 原生P2WPKH和P2WSH可用作默认更改地址,但这可能允许其他人轻松识别更改(参见下文)。
- 在广泛使用原生P2WPKH和P2WSH之前,这些地址类型可能会引起用户之间的隐私问题。
脚本和事务示例
安利2个比特币相关的交互式在线编程实战教程:
java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
这里是原文比特币隔离认证钱包开发指南