该BIP (Bitcoin Improvement Proposal) 定义了一种名为“隔离见证(Segregated Witness)”的新结构,它将交易签名等验证数据从交易Merkle树中分离出来,放入一个独立的“见证(witness)”结构中。隔离见证通过将签名数据从交易ID的计算中移除,解决了交易延展性问题,并为未来的扩展(如更大的区块大小,新的脚本系统)奠定了基础。
fork 自 bitcoin/bips
bip-anyprevout
在此仓库中搜索
/
复制路径
责编更多文件操作
责编更多文件操作
bip-0141: 澄清了 CHECKMULTISIG 的 sigop 计数
打开提交详情
2021年1月11日
644610f · 2021年1月11日
打开提交详情
331 行 (197 loc) · 25.3 KB
/
顶部
预览
代码
责编
331 行 (197 loc) · 25.3 KB
复制原始文件
下载原始文件
概要
编辑和原始操作
BIP: 141
Layer: Consensus (soft fork)
Title: Segregated Witness (Consensus layer)
Author: Eric Lombrozo <elombrozo@gmail.com>
Johnson Lau <jl2012@xbt.hk>
Pieter Wuille <pieter.wuille@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0141
Status: Final
Type: Standards Track
Created: 2015-12-21
License: PD
## 目录<br>固定链接:目录<br>- 摘要<br>- 动机<br>- 规范 <br> - 交易ID<br> - 承诺结构<br> - Witness程序<br> - 其他共识关键限制 <br> - 区块大小<br> - Sigops<br> - 其他定义 <br> - 交易大小计算<br> - 新的脚本语义<br>- 例子 <br> - P2WPKH<br> - 嵌套在BIP16 P2SH中的P2WPKH<br> - P2WSH<br> - 嵌套在BIP16 P2SH中的P2WSH<br> - 可扩展的承诺结构<br> - 无信任的未确认交易依赖链<br>- 未来扩展 <br> - SPV节点的紧凑型欺诈证明<br> - 新的脚本系统<br> - Per-input lock-time 和 relative-lock-time<br>- 向后兼容性<br>- 部署<br>- 鸣谢<br>- 脚注<br>- 参考实现<br>- 参考<br>- 版权 |
本BIP定义了一个名为“witness”的新结构,它与交易默克尔树分开提交到区块。此结构包含检查交易有效性所需的数据,但不包含确定交易影响所需的数据。特别是,脚本和签名被移动到这个新结构中。
该witness在一个树中提交,该树通过 coinbase 交易嵌套到区块现有的默克尔根中,目的是使该BIP与软分叉兼容。未来的硬分叉可以将此树放置在自己的分支中。
交易的全部效果由输出消耗(花费)和新输出创建决定。其他交易数据,特别是签名,仅用于验证区块链状态,而不是确定它。
通过从提交到交易默克尔树的交易结构中删除此数据,可以解决以下几个问题:
定义了一个新的数据结构 witness
。每个交易将有 2 个 ID。
txid
的定义保持不变:传统序列化格式的双 SHA256:
[nVersion][txins][txouts][nLockTime]
定义了一个新的 wtxid
:带有 witness 数据的新序列化的双 SHA256:
[nVersion][marker][flag][txins][txouts][witness][nLockTime]
nVersion
、txins
、txouts
和 nLockTime
的格式与传统序列化相同。
marker
必须是 1 字节的零值:0x00
。
flag
必须是 1 字节的非零值。目前,必须使用 0x01
。
witness
是交易所有 witness 数据的序列化。每个 txin 都与一个 witness 字段相关联。一个 witness 字段以一个 var_int
开头,用于指示 txin 的堆栈项的数量。后面跟着堆栈项,每个项以一个 var_int
开头,用于指示长度。Witness 数据不是脚本。
一个非 witness 程序(如下定义)txin 必须与一个空的 witness 字段相关联,表示为 0x00
。如果所有 txin 都不是 witness 程序,则交易的 wtxid
等于它的 txid
。
添加了一个新的区块规则,该规则要求对 wtxid
进行承诺。coinbase 交易的 wtxid
假定为 0x0000....0000
。
一个 witness root hash
是使用所有这些 wtxid
作为叶子计算出来的,方式类似于区块头中的 hashMerkleRoot
。
该承诺记录在 coinbase 交易的 scriptPubKey
中。它必须至少 38 个字节,前 6 个字节为 0x6a24aa21a9ed
,即:
1-byte - OP_RETURN (0x6a)
1-byte - Push the following 36 bytes (0x24)
4-byte - Commitment header (0xaa21a9ed)
32-byte - Commitment hash: Double-SHA256(witness root hash|witness reserved value)
39th byte onwards: Optional data with no consensus meaning
并且 coinbase 的输入的 witness 必须由一个 32 字节的数组组成,用于 witness reserved value
。
如果存在多个匹配该模式的 scriptPubKey
,则假定输出索引最高的那个是承诺。
如果一个区块中的所有交易都没有 witness 数据,则承诺是可选的。
一个 scriptPubKey
(或 BIP16/P2SH 中定义的 redeemScript
),它由一个 1 字节的推送操作码(对于 0 到 16)后跟一个介于 2 到 40 字节之间的数据推送组成,获得了一个新的特殊含义。第一个推送的值称为“版本字节”。以下推送的字节向量称为“witness程序”。
有两种情况会触发 witness 验证逻辑。每种情况都确定了 witness 版本字节和程序的位置,以及 scriptSig 的形式:
scriptPubKey
触发,该 scriptPubKey
正好是一个版本字节的推送,加上一个 witness 程序的推送。scriptSig 必须完全为空,否则验证失败。(“原生Witness程序”)scriptPubKey
是一个 P2SH 脚本时触发,并且在 scriptSig
中推送的 BIP16 redeemScript
正好是一个版本字节的推送加上一个 witness 程序的推送。scriptSig
必须正好是一个 BIP16 redeemScript
的推送,否则验证失败。(“P2SH Witness程序”)如果版本字节是 0,并且 witness 程序是 20 字节:
如果版本字节是 0,并且 witness 程序是 32 字节:
witnessScript
)。witnessScript
(≤ 10,000 字节) 从初始 witness 堆栈中弹出。witnessScript
的 SHA256 必须与 32 字节的 witness 程序匹配。witnessScript
被反序列化,并使用剩余的 witness 堆栈执行(每个堆栈项 ≤ 520 字节)。如果版本字节是 0,但 witness 程序既不是 20 字节也不是 32 字节,则脚本必须失败。[1]
如果版本字节是 1 到 16,则不会对 witness 程序或 witness 堆栈进行进一步的解释,并且对 witness 堆栈没有大小限制。这些版本保留供未来扩展使用。[2]
区块当前限制为 1,000,000 字节 (1MB) 的总大小。我们按如下方式更改此限制:
区块权重 定义为 基础大小 \* 3 + 总大小。(原理[3])
基础大小 是区块的大小(以字节为单位),采用原始交易序列化,不包含任何与 witness 相关的数据,如未升级节点所见。
总大小 是区块的大小(以字节为单位),使用 BIP144 中描述的序列化交易,包括基础数据和 witness 数据。
新规则是 区块权重 ≤ 4,000,000。
每个区块的 Sigops 当前限制为 20,000。我们按如下方式更改此限制:
当前公钥脚本、签名脚本和 P2SH 检查脚本中的 Sigops 按其先前值的 4 倍计算。 同样,sigop 限制也增加到 ≤ 80,000 的四倍。
每个 P2WPKH 输入都计为 1 个 sigop。此外,P2WSH witnessScript
中的操作码的计数方式与之前 P2SH redeemScript
中的计数方式相同。也就是说,CHECKSIG 仅计为 1 个 sigop。当以 OP_1 到 OP_16 开头时,CHECKMULTISIG 分别计为 1 到 16 个 sigops,否则计为 20 个 sigops。此规则适用于原生 witness 程序和 P2SH witness 程序。
以下定义不用于共识限制,但建议提供与上面介绍的术语一致的语言。
交易权重 定义为 基础交易大小 \* 3 + 总交易大小(即,与从 基础大小 和 总大小 计算 区块权重 的方法相同)。
虚拟交易大小 定义为 交易权重 / 4(向上舍入到下一个整数)。
基础交易大小 是剥离 witness 数据后序列化的交易的大小。
总交易大小 是交易的大小(以字节为单位),使用 BIP144 中描述的序列化,包括基础数据和 witness 数据。
尽管 P2WPKH 和 P2WSH 的脚本语言看起来与预隔离 witness 脚本非常相似,但仍有几个值得注意的差异。用户绝对不能 假设在预隔离 witness 系统中可花费的脚本也可用作 P2WPKH 或 P2WSH 脚本。在生产网络中进行大规模部署之前,开发人员应在测试网络上测试脚本,并启用默认的中继策略,并在 BIP141 在主网上激活后,使用少量资金进行测试。
BIP143 中描述了共识级别的一个主要区别,即版本 0 witness 程序中用于签名验证的新交易摘要算法。
在参考实现版本 0.13.1 中,隔离 witness 的第一个版本中还包含三个中继和挖掘策略。将来可能会提出基于这些策略的软分叉。为避免交易确认的无限期延迟以及潜在软分叉中的永久资金损失,用户必须 仔细观察新的语义:
以下示例是一个版本 0 的 pay-to-witness-public-key-hash (P2WPKH):
witness: <signature> <pubkey>
scriptSig: (empty)
scriptPubKey: 0 <20-byte-key-hash>
(0x0014{20-byte-key-hash})
scriptPubKey 中的“0”表示以下推送是版本 0 的 witness 程序。witness 程序的长度表示它是 P2WPKH 类型。该 witness 必须正好由 2 个项目组成。witness 中公钥的 HASH160 必须与 witness 程序匹配。
签名验证为
<signature> <pubkey> CHECKSIG
与传统的 P2PKH 输出相比,等效的 P2WPKH 在 scriptPubKey 中少占用 3 个字节,并将签名和公钥从 scriptSig 移动到 witness。
以下示例是相同的 P2WPKH,但嵌套在 BIP16 P2SH 输出中。
witness: <signature> <pubkey>
scriptSig: <0 <20-byte-key-hash>>
(0x160014{20-byte-key-hash})
scriptPubKey: HASH160 <20-byte-script-hash> EQUAL
(0xA914{20-byte-script-hash}87)
scriptSig 中的唯一项使用 HASH160 进行哈希处理,与 scriptPubKey 中的 20 字节脚本哈希进行比较,并解释为:
0 <20-byte-key-hash>
然后,公钥和签名按照前一个示例中的描述进行验证。
与之前的示例相比,scriptPubKey 大 1 个字节,scriptSig 大 23 个字节。虽然嵌套的 witness 程序效率较低,但自 0.6.0 版本以来,其支付地址对于所有比特币参考客户端都是完全透明且向后兼容的。
以下示例是一个 1-of-2 多重签名版本 0 的 pay-to-witness-script-hash (P2WSH)。
witness: 0 <signature1> <1 <pubkey1> <pubkey2> 2 CHECKMULTISIG>
scriptSig: (empty)
scriptPubKey: 0 <32-byte-hash>
(0x0020{32-byte-hash})
scriptPubKey 中的“0”表示以下推送是版本 0 的 witness 程序。witness 程序的长度表示它是 P2WSH 类型。witness 中的最后一项(“witnessScript”)被弹出,使用 SHA256 进行哈希处理,与 scriptPubKey 中的 32 字节哈希进行比较,并被反序列化:
1 <pubkey1> <pubkey2> 2 CHECKMULTISIG
该脚本使用 witness 中的剩余数据执行:
0 <signature1> 1 <pubkey1> <pubkey2> 2 CHECKMULTISIG
由于绕过了 520 字节的推送限制,因此 P2WSH 允许的最大脚本大小为 10,000 字节。
与 BIP16 P2SH 的 23 字节相比,scriptPubKey 占用 34 字节。增加的大小提高了针对可能发生的冲突攻击的安全性,因为 280 的工作量不再是不可行的(到 2015 年底,自从比特币创建以来,比特币挖矿中已经计算了 284 个哈希)。花费脚本与等效 BIP16 P2SH 输出的脚本相同,但已移至 witness。
以下示例是相同的 1-of-2 多重签名 P2WSH 脚本,但嵌套在 BIP16 P2SH 输出中。
witness: 0 <signature1> <1 <pubkey1> <pubkey2> 2 CHECKMULTISIG>
scriptSig: <0 <32-byte-hash>>
(0x220020{32-byte-hash})
scriptPubKey: HASH160 <20-byte-hash> EQUAL
(0xA914{20-byte-hash}87)
scriptSig 中的唯一项使用 HASH160 进行哈希处理,与 scriptPubKey 中的 20 字节哈希进行比较,并解释为:
0 <32-byte-hash>
然后,P2WSH witnessScript 按照前一个示例中的描述执行。
与之前的示例相比,scriptPubKey 小 11 个字节(安全性降低),而 witness 相同。但是,它还需要 scriptSig 中的 35 个字节。
coinbase 交易中的新承诺是 witness root hash
和 witness reserved value
的哈希。witness reserved value
当前没有共识含义,但将来允许为未来的软分叉提供新的承诺值。例如,如果将来需要新的共识关键承诺,则 coinbase 中的承诺变为:
Double-SHA256(Witness root hash|Hash(new commitment|witness reserved value))
为了向后兼容,Hash(new commitment|witness reserved value)
将转到 coinbase witness,而 witness reserved value
将记录在未来软分叉指定的另一个位置。可以通过这种方式添加任意数量的新承诺。
对于非比特币共识关键的承诺,例如合并挖掘,绝对不能 使用 witness reserved value
,以保留升级比特币共识协议的能力。
承诺之后的可选数据空间也为未来软分叉的元数据留出了空间,并且绝对不能 用于其他目的。
隔离 witness 从根本上解决了交易延展性的问题,这使得能够以无信任的方式构建未确认的交易依赖链。
Alice 和 Bob 双方可以同意将一定数量的比特币发送到 2-of-2 多重签名输出(“资金交易”)。在不签署资金交易的情况下,他们可以创建另一个交易,该交易在未来被锁定,将 2-of-2 多重签名输出花费到第三方帐户(“花费交易”)。Alice 和 Bob 将签署花费交易并交换签名。在检查签名后,他们将签署资金交易并将其提交到区块链。无需进一步操作,花费交易将在锁定时间后得到确认,并根据原始合同释放资金。它还保留了在锁定时间之前撤销原始合同的灵活性,可以通过另一个锁定时间较短的花费交易来实现,但前提是双方都同意。
使用 BIP62 作为延展性修复程序无法实现这种设置,因为在双方首先签署资金交易之前,无法创建花费交易。如果 Alice 在 Bob 之前透露了资金交易签名,则 Bob 能够无限期地锁定资金,而无需签署花费交易。
未确认的交易依赖链是更复杂的支付网络(如双工微支付通道和闪电网络)的基本构建块,这些网络有可能极大地提高比特币系统的可扩展性和效率。
比特币现在只有两种真正的安全模型。用户要么运行一个全节点,该节点使用系统中的所有规则验证每个区块,要么运行一个 SPV(简易支付验证)客户端,该客户端仅验证标头作为某些交易发布的证明。比特币白皮书建议,当 SPV 节点检测到无效区块时,可以接受来自全节点的警报,从而提示 SP```markdown
可以提交额外的见证数据,从而允许 SPV 节点可以快速验证的区块无效性的简短证明:
这些承诺可以通过软分叉包含在可扩展的承诺结构中,并且对于不理解这些新规则的节点是透明的。
由于在见证程序之前推送了一个版本字节,并且具有未知版本的程序始终被视为任何人都可以花费的脚本,因此可以通过软分叉引入任何新的脚本系统。见证作为一个结构不受任何现有脚本语义和约束的限制,特别是 520 字节的推送限制,因此允许任意大的脚本和签名。
新的脚本系统的示例包括 Schnorr 签名,它可以显着减小多重签名交易的大小,Lamport 签名,它具有抗量子计算能力,以及 Merklized 抽象语法树,它允许非常复杂的条件脚本的非常紧凑的见证。
目前,交易中只有一个 nLockTime 字段,所有输入必须共享相同的值。BIP68 允许使用 nSequence 字段来实现每个输入的相对锁定时间,但是锁定时间段和分辨率有限。
通过软分叉,可以引入一个单独的见证结构来允许每个输入的锁定时间和相对锁定时间,以及一个可以签名和操作新数据的新脚本系统(如 BIP65 和 BIP112)。
作为软分叉,旧软件将继续运行而无需修改。但是,未升级的节点将看不到也不会验证见证数据,并将所有见证程序视为任何人都可以花费的脚本(除了少数见证程序等于 0 的边缘情况,这种情况下脚本必须失败)。钱包应始终警惕任何人都可以花费的脚本,并以怀疑的态度对待它们。强烈建议未升级的节点进行升级,以便利用新功能。
未升级的钱包可以做什么
未升级的钱包不能做什么
此 BIP 将通过名为 “segwit” 且使用位 1 的 “版本位” BIP9 部署。
对于比特币主网,BIP9 启动时间为 2016 年 11 月 15 日 UTC 午夜(Epoch 时间戳 1479168000),BIP9 超时时间为 2017 年 11 月 15 日 UTC 午夜(Epoch 时间戳 1510704000)。
对于比特币测试网,BIP9 启动时间为 2016 年 5 月 1 日 UTC 午夜(Epoch 时间戳 1462060800),BIP9 超时时间为 2017 年 5 月 1 日 UTC 午夜(Epoch 时间戳 1493596800)。
特别感谢 Gregory Maxwell 提出了此 BIP 中的许多想法,并感谢 Luke-Jr 弄清楚了如何将其部署为软分叉。
CastToBool
值为零,则脚本必须失败。但是,拥有这样的哈希是对哈希函数的成功原像攻击,并且风险可以忽略不计。本文档置于公共领域。
>- 原文链接: [github.com/ajtowns/bips/...](https://github.com/ajtowns/bips/blob/bip-anyprevout/bip-0141.mediawiki)
>- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!