本文档是 BIP-0341 的修改版本,描述了 Elements 中 Taproot 输出使用的签名哈希。其中与 BIP-0341 不同的地方用 NEW 标明。此外,BIP 341 和 342 中的四个标记哈希标签 TapLeaf、TapBranch、TapTweak 和 TapSighash 都带有后缀 /elements。
跳至内容
ElementsProject/ elements Public
折叠文件树
文件
master
搜索此仓库
/
taproot-sighash.mediawiki
复制路径
Blame更多文件操作
Blame更多文件操作
最新提交
apoelstra
doc: fix SigMsg length in taproot sighash
2021年7月1日
cca8224 · 2021年7月1日
历史
历史
打开提交详情
查看此文件的提交历史。
65 行 (52 行代码) · 7.27 KB
/
taproot-sighash.mediawiki
顶部
文件元数据和控件
65 行 (52 行代码) · 7.27 KB
Raw
复制原始文件
下载原始文件
轮廓
编辑和原始操作
简介
Permalink: Introduction
本文档是 BIP-0341 的修改副本,其中描述了 Elements 中用于 Taproot 输出的签名哈希。
与 BIP-0341 不同的项目用 NEW 表示。
除了本文档中的更改外,BIP 341 和 342 中的四个标记哈希标签 TapLeaf、TapBranch、TapTweak 和 TapSighash 都带有后缀 /elements。
通用签名消息
Permalink: Common signature message
函数 SigMsg(hash_type, ext_flag) 计算作为字节数组签名的消息。它也隐式地是花费交易和它花费的输出的函数,但这些没有列出以保持符号简单。
参数 hash_type 是一个 8 位无符号值。重用了来自传统脚本系统的 SIGHASH 编码,包括 SIGHASH_ALL、SIGHASH_NONE、SIGHASH_SINGLE 和 SIGHASH_ANYONECANPAY,加上默认的 hash_type 值 0x00,它导致像 SIGHASH_ALL 一样对整个交易进行签名。以下限制适用,如果违反,会导致验证失败:
- 使用任何未定义的 hash_type (不是 0x00、0x01、0x02、0x03、0x81、0x82 或 0x83)。
-
使用 SIGHASH_SINGLE 而没有“相应的输出”(一个与被验证输入具有相同索引的输出)。
NEW 如果正在考虑的输入是一个 pegin 输入,则字段 nAsset、nValue 和 scriptPubKey(如果它们出现)取自 pegin witness 数据。使用的资产是侧链上的资产 ID,而不是父链上的资产 ID(如果有)。
NEW 签名哈希之前添加的 epoch 字段完全删除。 如果 elements 中的 taproot 签名哈希有新的更新,他们将会使用新的 tagged hashes 来代替增加 epochs。
参数 ext_flag 是范围在 0-127 之间的整数,用于指示(在消息中)在消息末尾添加了扩展。
如果参数采用可接受的值,则消息是以下数据的连接,按顺序排列(每个项目的大小以字节为单位列出)。2、4 或 8 字节的数值以小端编码。
- NEW 区块链数据:(理由:即使pubkeys被重用,签名也不能在不同的 Elements 实例中重用。)
- genesis_block (32): 区块链的创世区块的哈希值
- genesis_block (32): 再次创世哈希
- 控制:
- 交易数据:
- nVersion (4): 交易的 nVersion。
- nLockTime (4): 交易的 nLockTime。
- 如果 hash_type & 0x80 不等于
SIGHASH_ANYONECANPAY:
- NEW sha_outpoint_flags (32): 输入的 outpoint flags 右移 24 位后,每个输入一个字节的连接序列化的 SHA256。(pegin 输入的字节将是 0x40。发行输入的字节将是 0x80。pegin 和发行版输入的字节都将是 0xc0。)
- sha_prevouts (32): 所有输入 outpoint 的序列化的 SHA256。每个 prevout 输出索引是排除 outpoint flags 的掩码版本。 如上所述,对于 pegin 输入,这些将是父链上的 prevout。
- NEW sha_asset_amounts (32): 每个输出的 nAsset||nValue 的序列化的 SHA256。如上所述,对于 pegin 输入,将使用显式值(来自父链)和资产(peg 资产)。
- sha_scriptpubkeys (32): 所有花费的输出 scriptPubKey 的序列化的 SHA256。
- sha_sequences (32): 所有输入 nSequence 的序列化的 SHA256。
- NEW sha_issuances (32): 具有发行版的输入的资产发行数据的连接序列化的 SHA256,没有发行版的输入为 0x00。(这匹配此哈希的 Segwit v0 编码。)
- NEW sha_issuance_rangeproofs (32): 所有输入的 issuanceAmountRangeproof||inflationKeysRangeproof 的连接的序列化的 SHA256,其中每个字段都编码为 0x00 (如果不存在, 或者存在显式发行时)
- 如果 hash_type & 3 不等于
SIGHASH_NONE 或 SIGHASH_SINGLE:
- sha_outputs (32): 以
CTxOut 格式的所有输出的序列化的 SHA256。
- NEW sha_output_witnesses (32): 以
CTxOutWitness 格式的所有输出见证(范围证明和防伪证明)的序列化的 SHA256。
- 关于此输入的数据:
- spend_type (1): 等于 (ext_flag * 2) + annex_present,其中 annex_present 如果不存在 annex 则为 0,否则为 1(原始 witness 栈有两个或多个 witness 元素,并且最后一个元素的第一个字节是 0x50)
- 如果 hash_type & 0x80 等于
SIGHASH_ANYONECANPAY:
- NEW outpoint_flag (1): 输入的 outpoint flags 右移 24 位。(比较上面的 sha_outpoint_flags 。)
- outpoint (36): 此输入的
COutPoint(32 字节哈希 + 4 字节小端),其中输出索引不包括 outpoint flags。
- NEW nAsset (33): 此输入花费的先前输出的 (可能保密的) assetID
- NEW nValue (9-33): 此输入花费的先前输出的 (可能保密的) 金额
- scriptPubKey (35): 此输入花费的先前输出的 scriptPubKey,序列化为
CTxOut 中的脚本。它的大小始终为 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 不等于
SIGHASH_ANYONECANPAY:
- input_index (4): 此输入在交易输入向量中的索引。第一个输入的索引是 0。
- 如果存在 annex(设置了 spend_type 的最低位):
- sha_annex (32): (compact_size(annex 的大小) || annex) 的 SHA256,其中 annex 包括强制性的 0x50 前缀。
- 关于此输出的数据:
- 如果 hash_type & 3 等于
SIGHASH_SINGLE:
- sha_single_output (32): 以
CTxOut 格式的相应输出的 SHA256。
- NEW sha_single_output_witness (32): 以
CTxOutWitness 格式的相应输出见证(范围证明和防伪证明)的序列化的 SHA256。
SigMsg() 的总长度对于 ANYONECANPAY sighash 为 257--442 字节,对于非 ANYONECANPAY sighash 为 366 字节,并且对于 SIGHASH_NONE sighash,这两个数字都减少了 64 字节,如果存在 annex,则增加 32 字节。 请注意,这不包括诸如 sha_prevouts 之类的子哈希的大小,这些子哈希可能会在同一交易的签名之间缓存。