比特币钱包隔离认证开发指南

时间: 2018年11月2日

来源:OSCHINA

翻译自:https://bitcoincore.org/en/segwit_wallet_dev/#basic-segregated-witness-support

本文件的大部分内容可以在与隔离认证相关的BIP中找到,包括BIP141BIP143BIP144BIP145。请将此视为阅读其他相关文件的第一个参考点,并作为那些应该做和那些不应该做的检查清单。

基本的隔离认证支持

钱包必须实现本节中的所有功能,以便在基本级别被视为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。

交易序列化

  • 兼容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 ,表示见证堆栈项的数量为零。
  • 如果交易中的所有 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。
  • 对脚本的限制
    • 脚本评测不能失败,并且必须在评测后留下一个且只有一个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之前,这些地址类型可能会引起用户之间的隐私问题。

脚本和事务示例

相关文章:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注