该BIP (Bitcoin Improvement Proposal) 提议定义了一种新的数据结构“witness”,它与交易的Merkle树分开提交到区块中。这个结构包含了验证交易有效性所需的数据,但不需要确定交易的影响。通过将脚本和签名移动到这个新的结构中,解决了交易延展性问题,并为SPV节点提供了更紧凑的欺诈证明,同时为未来的扩展提供了可能性。
forked from bitcoin/bips
vault
在此仓库中搜索
/
复制路径
Blame更多文件操作
Blame更多文件操作
Promote BIP 2 Draft->Active, and implement it
打开提交详情
2016年11月30日
959fecc · 2016年11月30日
打开提交详情
330 行 (196 LOC) · 25.2 KB
/
顶部
预览
代码
Blame
330 行 (196 LOC) · 25.2 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: Draft
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> - 每个输入的锁定时间和相对锁定时间<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
。
使用所有这些wtxid
作为叶子计算witness root hash
,方式类似于区块头中的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保留值)
第39个字节之后: 没有共识意义的可选数据
并且coinbase的输入的 Witness必须由一个32字节的数组组成,用于witness reserved value
。
如果存在多个与该模式匹配的scriptPubKey
,则假设具有最高输出索引的scriptPubKey
是承诺。
如果区块中的所有交易都没有 Witness数据,则承诺是可选的。
由1字节的推送操作码(0到16)组成的scriptPubKey
(或BIP16/P2SH中定义的redeemScript
),后跟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 字节)。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。
每个区块的 Sigop 目前限制为 20,000。我们按如下方式更改此限制:
当前 pubkey 脚本、签名脚本和 P2SH 检查脚本中的 Sigop 按其先前值的 4 倍计算。 Sigop 限制同样增加到 ≤ 80,000。
每个 P2WPKH 输入都计为 1 个Sigop。此外,P2WSH witnessScript
中的操作码的计数方式与之前在 P2SH redeemScript
中相同。也就是说,CHECKSIG 仅计为 1 个Sigop,而 CHECKMULTISIG 根据参数计为 1 到 20 个sigop。此规则适用于原生 Witness程序和 P2SH Witness程序。
以下定义不用于共识限制,但建议提供与上面介绍的术语一致的语言。
交易权重 定义为 基础交易大小 \* 3 + 总交易大小(即,与从基础大小和总大小计算区块权重的方法相同)。
虚拟交易大小 定义为 交易权重 / 4(向上舍入到下一个整数)。
基础交易大小是以剥离 Witness数据的方式序列化的交易的大小。
总交易大小是以字节为单位的交易大小,交易序列化如BIP144中所述,包括基础数据和 Witness数据。
尽管 P2WPKH 和 P2WSH 的脚本语言看起来与隔离 Witness之前的脚本非常相似,但也存在一些显着的差异。用户一定不能认为在隔离 Witness 之前的系统中可花费的脚本也可以作为 P2WPKH 或 P2WSH 脚本花费。在生产网络中进行大规模部署之前,开发人员应该在 testnet 上使用默认的 relay 策略打开来测试脚本,并在 BIP141 在主网上激活后用少量资金进行测试。
BIP143中描述了共识层面的一个主要区别,即版本 0 Witness程序中用于签名验证的新交易摘要算法。
隔离 Witness 的第一个版本 0.13.1 的参考实现中还包含三个 relay 和挖矿策略。基于这些策略的软分叉很可能在不久的将来提出。为了避免交易确认的无限期延迟以及潜在的软分叉中的永久资金损失,用户必须仔细观察新的语义:
以下示例是版本 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。
固定链接: 嵌套在 BIP16 P2SH 中的 P2WPKH
以下示例是相同的 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
P2WSH 允许的最大脚本大小为 10,000 字节,因为绕过了 520 字节的推送限制。
scriptPubKey 占据 34 个字节,而不是 BIP16 P2SH 的 23 个字节。增加的大小提高了针对可能的冲突攻击的安全性,因为 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保留值))
为了向后兼容,Hash(new commitment|witness reserved value)
将进入 coinbase Witness,并且witness reserved value
将被记录在未来软分叉指定的另一个位置。可以通过这种方式添加任意数量的新承诺。
对Bitcoin 不具有共识关键意义的任何承诺,例如合并挖矿,一定不能使用witness reserved value
来保留升级比特币共识协议的能力。
承诺之后的可选数据空间也为未来软分叉的元数据留下了空间,一定不能用于其他目的。
隔离 Witness 从根本上解决了交易可延展性的问题,这使得能够以无信任的方式构建未确认的交易依赖链。
双方,Alice 和 Bob,可以同意将一定数量的比特币发送到 2-of-2 多重签名输出(“资金交易”)。在未签署资金交易的情况下,他们可以创建另一笔交易,该交易在未来被锁定,将 2-of-2 多重签名输出花费到第三方帐户(“支出交易”)。Alice 和 Bob 将签署支出交易并交换签名。在检查签名后,他们将签署资金交易并将其提交到区块链。无需进一步操作,支出交易将在锁定时间后得到确认,并根据原始合同释放资金。它还保留了在锁定时间之前撤销原始合同的灵活性,可以通过另一个锁定时间较短的支出交易来撤销,但只能通过双方的相互同意。
使用 BIP62 作为可延展性修复是不可能实现这种设置的,因为如果没有双方首先签署资金交易,就无法创建支出交易。如果 Alice 在 Bob 之前透露了资金交易签名,Bob 就能够无限期地锁定资金,而无需签署支出交易。
未确认的交易依赖链是更复杂的支付网络的基本构建块,例如双工微支付通道和闪电网络,这些网络有可能极大地提高比特币系统的可扩展性和效率。
比特币现在只有两个真正的安全模型。用户要么运行一个完整节点,该节点使用系统中的所有规则验证每个区块,要么运行一个 SPV(简单支付验证)客户端,该客户端仅验证标头作为某些交易发布的证明。比特币白皮书建议,当完整节点检测到无效区块时,SPV 节点可能会接受来自完整节点的警报,从而提示 SPV 节点下载有问题的区块和交易以进行验证。然而,这种方法可能会成为一种 DoS 攻击媒介,因为生成虚假警报几乎没有成本。警报必须附带一个紧凑但具有确定性的欺诈证明。
在当前的比特币协议中,几乎所有规则都可以生成紧凑的欺诈证明,除了以下几个规则:
可以提交额外的 Witness数据,从而允许 SPV 节点快速验证的区块无效性的简短证明:
由于版本字节在见证程序之前被推送,并且具有未知版本的程序始终被视为任何人都可以花费的脚本,因此可以通过软分叉引入任何新的脚本系统。作为一种结构的见证不受任何现有脚本语义和约束的限制,特别是520字节的推送限制,因此允许任意大的脚本和签名。
新的脚本系统的示例包括 Schnorr 签名(可以显著减少多重签名交易的大小)、Lamport 签名(具有抗量子计算能力)和 Merklized abstract syntax trees(允许非常紧凑的见证,用于具有极端复杂性的条件脚本)。
目前,一个交易中只有一个 nLockTime 字段,所有输入必须共享相同的值。BIP68 允许使用 nSequence 字段实现每输入相对锁定时间,但是锁定时间段和分辨率有限。
通过软分叉,可以引入一个单独的见证结构来允许每输入锁定时间和相对锁定时间,以及一个新的脚本系统,可以签名和操作新数据(如 BIP65 和 BIP112)。
作为软分叉,旧软件将继续无需修改即可运行。但是,未升级的节点将看不到或验证见证数据,并将所有见证程序视为任何人都可以花费的脚本(除了一些见证程序等于0的极端情况,在这种情况下,脚本必须失败)。钱包应始终警惕任何人都可以花费的脚本,并以怀疑的态度对待它们。强烈建议未升级的节点进行升级,以利用新功能。
未升级的钱包可以做什么
未升级的钱包不能做什么
此 BIP 将通过名称为“segwit”且使用 bit 1 的“version bits” 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/jl2012/bips/b...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!