Elements中的Taproot输出的签名哈希

本文档描述了Elements中用于Taproot输出的签名哈希,是BIP-0341的修改副本,并指出了与BIP-0341的不同之处。同时,BIPs 341和342中的四个tagged hash tags “TapLeaf”,“TapBranch”,“TapTweak”和“TapSighash”都附加了“/elements”。

==== 简介 ====

本文档是 [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP-0341] 的修改副本,描述了 Elements 中用于 Taproot 输出的签名哈希。 与 BIP-0341 不同的项目用 '''''NEW''''' 表示。

除了本文档中的更改之外,BIP 341 和 342 中的四个标记哈希标签 ''TapLeaf''、''TapBranch''、''TapTweak'' 和 ''TapSighash'' 都附加了 <tt>/elements</tt>。

==== 通用签名消息 ====

函数 ''SigMsg(hash_type, ext_flag)'' 计算作为字节数组签名的消息。 它也隐含地是花费交易和它花费的输出的函数,但为了保持符号简单,这些没有列出。

参数 ''hash_type'' 是一个 8 位无符号值。 重用了来自旧脚本系统的 <code>SIGHASH</code> 编码,包括 <code>SIGHASH_ALL</code>、<code>SIGHASH_NONE</code>、<code>SIGHASH_SINGLE</code> 和 <code>SIGHASH_ANYONECANPAY</code>,以及默认的 ''hash_type'' 值 ''0x00'',这会导致对整个交易进行签名,就像 <code>SIGHASH_ALL</code> 一样。 以下限制适用,如果违反这些限制,将导致验证失败:

  • 使用任何未定义的 ''hash_type''(不是 ''0x00''、''0x01''、''0x02''、''0x03''、''0x81''、''0x82'' 或 ''0x83'')。
  • 使用 <code>SIGHASH_SINGLE</code> 而没有“对应的输出”(与正在验证的输入具有相同索引的输出)。

'''''NEW''''' 如果正在考虑的输入是 pegin 输入,则字段 ''nAsset''、''nValue'' 和 ''scriptPubKey''(如果它们出现)取自 pegin witness 数据。 使用的资产是侧链上的资产 ID,而不是父链上的资产 ID(如果有)。

'''''NEW''''' 签名哈希之前附加的 epoch 字段已完全删除。 如果 elements 中有新的 taproot 签名哈希更新,它们将使用新的标记哈希,而不是递增 epoch

参数 ''ext_flag'' 是 0-127 范围内的整数,用于(在消息中)指示在消息末尾添加了扩展。

如果参数采用可接受的值,则消息是以下数据的串联,按顺序排列(每个项目的大小以字节为单位列出)。 2、4 或 8 字节的数值以小端字节序编码。

  • '''''NEW''''' 区块链数据:(理由:即使重用公钥,签名也不能在不同的 Elements 实例中重用。) ''genesis_block'' (32):区块链创世区块的哈希值 ''genesis_block'' (32):再次是创世哈希值
  • 控制: ** ''hash_type'' (1)。
  • 交易数据: ''nVersion'' (4):交易的 ''nVersion''。 ''nLockTime'' (4):交易的 ''nLockTime''。 如果 ''hash_type & 0x80'' 不等于 <code>SIGHASH_ANYONECANPAY</code>: ** '''''NEW''''' ''sha_outpoint_flags'' (32):每个输入的 outpoint 标志右移 24 位后串联的序列化的 SHA256。(pegin 输入的字节将为 0x40。issuance 输入的字节将为 0x80。pegin 和 issuance 的字节都将为 0xc0。) ''sha_prevouts'' (32):所有输入 outpoint 序列化的 SHA256。 每个 prevout 输出索引都是排除 outpoint 标志的掩码版本。 如上所述,对于 pegin 输入,这些将是父链上的 prevout。 '''''NEW''''' ''sha_asset_amounts'' (32):每个输出的 ''nAsset||nValue'' 的序列化的 SHA256。 如上所述,对于 pegin 输入,将使用显式值(来自父链)和资产(Hook资产)。 ''sha_scriptpubkeys'' (32):所有花费的输出 ''scriptPubKey'' 的序列化的 SHA256。 ''sha_sequences'' (32):所有输入 ''nSequence'' 的序列化的 SHA256。 '''''NEW''''' ''sha_issuances'' (32):具有 issuance 的输入的资产发行数据的串联的序列化的 SHA256,或者没有 issuance 的输入的 ''0x00''。 (这与 Segwit v0 对此哈希的编码相匹配。) * '''''NEW''''' ''sha_issuance_rangeproofs'' (32):所有输入的 ''issuanceAmountRangeproof||inflationKeysRangeproof'' 串联的序列化的 SHA256,其中每个字段都被编码为 ''0x00''(如果不存在)(如果不存在 issuance,或者如果存在显式发行) * 如果 ''hash_type & 3'' 不等于 <code>SIGHASH_NONE</code> 或 <code>SIGHASH_SINGLE</code>: ''sha_outputs'' (32):<code>CTxOut</code> 格式的所有输出的序列化的 SHA256。 *** '''''NEW''''' ''sha_output_witnesses'' (32):<code>CTxOutWitness</code> 格式的所有输出 witness(范围证明和防伪证明)的序列化的 SHA256。
  • 关于此输入的数据: ''spend_type'' (1):等于 ''(ext_flag * 2) + annex_present'',其中 ''annex_present'' 如果不存在 annex 则为 0,否则为 1(原始 witness 堆栈有两个或多个 witness 元素,并且最后一个元素的第一个字节是 ''0x50'') * 如果 ''hash_type & 0x80'' 等于 <code>SIGHASH_ANYONECANPAY</code>: '''''NEW''''' ''outpoint_flag'' (1):输入的 outpoint 标志右移 24 位。 (比较上面的 ''sha_outpoint_flags''。) ''outpoint'' (36):此输入的 <code>COutPoint</code>(32 字节哈希 + 4 字节小端字节序),其中输出索引不包括 outpoint 标志。 '''''NEW''''' ''nAsset'' (33):此输入花费的先前输出的(可能是机密的)assetID '''''NEW''''' ''nValue'' (9-33):此输入花费的先前输出的(可能是机密的)金额 ''scriptPubKey'' (35):此输入花费的先前输出的 ''scriptPubKey'',以 <code>CTxOut</code> 中的脚本形式序列化。 它的大小始终为 35 字节。 ''nSequence'' (4):此输入的 ''nSequence''。 '''''NEW''''' ''asset_issuance'' (1-130):如果 ''outpoint_flag & 0x80 == 0x80'':此输入的资产发行数据,否则为 ''0x00'' * '''''NEW''''' ''sha_single_issuance_rangeproofs'' (0-32):如果 ''outpoint_flag & 0x80 == 0x80'':此输入的 ''issuanceAmountRangeproof||inflationKeysRangeproof'' 串联的序列化的 SHA256,其中每个字段都被编码为 ''0x00''(如果不存在) * 如果 ''hash_type & 0x80'' 不等于 <code>SIGHASH_ANYONECANPAY</code>: ''input_index'' (4):此输入在交易输入向量中的索引。 第一个输入的索引为 0。 ** 如果存在 annex(''spend_type'' 的最低位已设置): *** ''sha_annex'' (32):''(compact_size(annex 大小) || annex)'' 的 SHA256,其中 ''annex'' 包括强制性的 ''0x50'' 前缀。
  • 关于此输出的数据: 如果 ''hash_type & 3'' 等于 <code>SIGHASH_SINGLE</code>: ** ''sha_single_output'' (32):<code>CTxOut</code> 格式的相应输出的 SHA256。 '''''NEW''''' ''sha_single_output_witness'' (32):<code>CTxOutWitness</code> 格式的相应输出 witness(范围证明和防伪证明)的序列化的 SHA256。

对于 <code>ANYONECANPAY</code> sighash,''SigMsg()'' 的总长度为 ''257--442'' 字节,对于非 <code>ANYONECANPAY</code> sighash,总长度为 ''366'' 字节,对于 <code>SIGHASH_NONE</code> sighash,这两个数字都减少了 64 字节,如果存在 annex,则增加 32 字节。 请注意,这不包括子哈希的大小,例如 ''sha_prevouts'',它可以在相同交易的签名之间缓存。

  • 原文链接: github.com/ElementsProje...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
raw.githubusercontent
raw.githubusercontent
江湖只有他的大名,没有他的介绍。