主页 > www.token.im > 比特币脚本csdn 在一篇文章中阅读 P2SH 和 P2WSH

比特币脚本csdn 在一篇文章中阅读 P2SH 和 P2WSH

www.token.im 2023-05-11 07:12:40

P2SH和P2WSH是比特币交易的高级脚本,可以构建复杂条件的智能合约交易。

首先,我们来看看多重签名脚本。 接下来介绍最常见的交易脚本,P2SH,Pay-to-Script-Hash,打开复杂脚本的世界。 最后介绍一下P2WSH,即Pay-to-Witness-Script-Hash支付给witness script hash。 P2WSH 的结构性调整对比特币交易产生了多方面的影响。

1. 多重签名

多重签名脚本设置了一个条件,即脚本中记录了N个公钥,并且至少有M个必须提供签名才能解锁资金。 这也称为 MN 方案,其中 N 是密钥总数,M 是验证所需的签名数。 例如,2/3 多重签名是三个公钥被列为潜在签名者并且至少需要 2 个有效签名才能花费资金。 此时,标准多重签名脚本被限制为最多列出 15 个公钥,这意味着您可以执行 1 到 15 个多重签名或该范围内的任意组合。 在本书出版之前,可能会取消列出 15 个密钥的限制,因此请检查 isStandard() 函数以查看网络当前接受的内容。

设置 MN 多重签名条件的锁定脚本的一般形式是:

M   ...  N CHECKMULTISIG

M 是花费输出所需的签名数,N 是列出的公钥总数。 设置 2 到 3 多重签名条件的锁定脚本如下所示:

2    3 CHECKMULTISIG

上述锁定的脚本可以通过包含签名和公钥的脚本解锁:或者通过三个存档公钥中任意两个一致私钥的签名组合解锁。 这两个脚本组合在一起将形成一个验证脚本:

  2    3 CHECKMULTISIG

执行时,只有当脚本的解锁版本与解锁脚本设置的条件匹配时,组合脚本才会将结果显示为True。

上例中对应的设置条件为:解锁脚本中是否包含三个公钥中任意两个对应私钥的有效签名。

l CHECKMULTISIG执行bug

CHECKMULTISIG 的实现中存在一个错误,需要一些小的解决方法。 当 CHECKMULTISIG 执行时,它应该消耗堆栈中的 M + N + 2 个项目作为参数。 但是,由于该错误,CHECKMULTISIG 会弹出(pop)一个额外的值或一个超出预期的值。

让我们看一下这个更详细的/使用以前的/验证示例:

  2    3 CHECKMULTISIG

首先,CHECKMULTISIG 弹出最顶层的项目,即 N(本例中 N 为“3”)。 然后它弹出 N 项,这是可以签名的公钥。 在此示例中,公钥 A、B 和 C。然后,它将一个项目 M 弹出到法定人数(需要多少个签名)。 这里M=2,此时CHECKMULTISIG应该弹出最后的M项,也就是签名,看看是否有效。

然而不幸的是,实现中的一个错误导致 CHECKMULTISIG 弹出一个项目(总共 M+1 个)。 检查签名时,不考虑额外的项目,因此它对 CHECKMULTISIG 本身没有直接影响。 但是,额外的值必须存在比特币脚本csdn,因为如果它不存在,当 CHECKMULTISIG 尝试弹出一个空堆栈时,它会导致堆栈错误并且脚本将失败(将事务标记为无效)。 由于多余的项目被忽略,它可以是任何东西,但通常使用 0。 由于该错误已成为共识规则的一部分,因此现在必须永远重现它。 所以正确的脚本验证应该是这样的:

0   2    3 CHECKMULTISIG

所以解锁脚本不是如下:

 

反而:

0  

从现在开始,如果你看到一个多重签名解锁脚本,你应该会看到一个额外的 0 开始,它的唯一目的是解决一个意外成为共识规则解决方法的错误。

即确保示例中有3个私钥签名对应3个公钥来校验多重签名,从而保证脚本不会产生bug。

2. P2SH (Pay-to-Script-Hash)

P2SH 作为一种新的、强大的交易类型于 2012 年推出,可大大简化复杂的交易脚本。 为了进一步说明P2SH的必要性,我们先来看一个实际的例子。

Mohammed,一家总部位于迪拜的电子产品进口商。 Mohammed 的公司采用比特币多重签名作为其公司会计账簿的要求。 多重签名脚本是比特币高级脚本最常见的应用之一,是具有相当影响力的脚本。 对于所有客户付款(即应收账款),Mohammed 的公司都需要多重签名交易。 基于多重签名机制,客户的任何一笔支付都需要至少两个签名才能解锁,一个来自穆罕默德,另一个来自他的合作伙伴或具有备用密钥的代理人。 这样的多重签名机制可以为公司治理提供管控便利,也可以有效防止盗窃、盗用和丢失。 最后的脚本很长:

    2  
      5 OP_C HECKMULTISIG

多重签名虽然很强大,但是使用起来还是不方便。 基于之前的脚本,Mohammed必须在客户付款之前将脚本发送给每个客户,并且每个客户还必须使用可以生成客户交易脚本的特殊比特币钱包软件,并且每个客户都必须学习如何使用脚本来完成交易.

此外,由于脚本可能包含极长的公钥,最终的交易脚本可能是初始交易脚本的 5 倍之多。 额外长度的脚本将成为客户的成本负担。 最后,一个长长的交易脚本会被记录在所有节点RAM的UTXO集合中,直到资金被花完。 采用如此复杂的输出脚本,在实际交易中难度较大。

P2SH 就是为了解决这个实际问题而引入的,它旨在让复杂脚本的使用变得像直接向比特币地址支付一样简单。 在P2SH支付中,复杂的锁定脚本被电子指纹所取代,电子指纹指的是密码学中的哈希值。

当交易尝试支付 UTXO 时,要解锁支付脚本,它必须包含与哈希匹配的脚本。 P2SH的意思是支付匹配hash的脚本,支付输出时,后面会渲染脚本。

在 P2SH 交易中,锁定脚本被一个经过哈希处理的 20 字节哈希值取代,称为赎回脚本。 因为它是在赎回时出现在系统中的,而不是锁定脚本模式。

下表列出了 P2SH 脚本。

比特币脚本csdn_比特币平台关闭后比特币怎么办_比特币主连比特币连续的区别

从表中可以看出,对于 P2SH,锁定脚本中没有显示详细说明输出条件的复杂脚本(赎回脚本)。

相反,只有它的哈希值在锁定脚本中呈现,赎回脚本本身在稍后呈现,作为输出用完时解锁脚本的一部分。 这将交易费用从发送方转移到收款人,并将复杂的计算工作从发送方转移到收款人。

P2SH 交易使用锁定脚本将输出与哈希相关联,而不是与特别长的前导脚本相关联。 使用的锁定脚本是:

HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e EQUAL

如您所见,此脚本比之前的长脚本短得多。 这个 P2SH 不是“支付给 5 个多重签名脚本”,而是等同于“用这个哈希支付给脚本”。 客户在向 Mohammed 公司付款时,只需要在他们的付款说明中包含这个非常短的锁定脚本。 当Mohammed要花费这个UTXO时,附上原始赎回脚本(用UTXO哈希锁定)和必要的解锁签名,例如:

   <2 PK1 PK2 PK3 PK4 PK5 5 CHECKMULTISIG>

这两个脚本分两步组合。 首先,将赎回脚本与锁定脚本进行比较,看是否与哈希匹配:

<2 PK1 PK2 PK3 PK4 PK5 5 CHECKMULTISIG> HASH160  EQUAL

如果赎回脚本与哈希匹配,则执行解锁脚本以释放赎回脚本:

  2 PK1 PK2 PK3 PK4 PK5 5 CHECKMULTISIG

3. P2WSH (Pay-to-Witness-Script-Hash)

P2WSH 是一种支持隔离见证的 P2SH。 我们首先介绍孤立证人的概念。

隔离见证是比特币的一种结构调整,旨在将见证数据部分从交易的scriptSig(解锁脚本)字段移动到伴随交易的单独见证数据结构中。 当客户端请求交易数据时,可以选择要不要伴随这部分的见证数据。

隔离见证由以下 BIP 定义:

BIP-141隔离见证的主要定义

BIP-143 版本 0 见证程序的交易签名验证

BIP-144 点对点服务 - 新的网络消息传递和序列化格式

BIP-145 隔离见证的 getblocktemplate 升级(适用于矿工)

l 为什么需要隔离见证?

隔离见证是一种结构性变化,将对多个方面产生影响——可扩展性、安全性、经济激励和比特币整体性能:

l 交易延展性

见证从交易中移除后,用作标识符的交易哈希不再包含见证数据。 由于见证数据是交易中唯一可以被第三方修改的部分(见交易标识符部分),删除它也消除了交易延展性攻击的机会。通过隔离见证,交易对任何人都变得不可变(除了creator himself),这大大提高了许多其他依赖高级比特币交易架构的协议的性能。

可执行性。 例如支付渠道、交叉连接交易和闪电网络。

l 脚本版本管理

隔离见证脚本引入后,类似于交易和区块都有版本号,每个锁定脚本也有一个脚本版本号。 脚本版本号的条件允许脚本语言以向后兼容的方式升级(即软分叉升级)以引入新的脚本操作数、句法或语义。 无损升级脚本语言的能力将大大加快比特币的创新速度。

l 网络和存储扩展

见证数据通常是整体交易量的重要贡献者。 更复杂的脚本通常非常大,例如用于多重签名或支付渠道的脚本。 有时这些脚本会占据交易的很大一部分(超过 75%)。 隔离见证通过将见证数据移出交易来提高比特币的可扩展性。 节点可以在验证签名后移除见证数据,或者在进行简单的支付验证时完全忽略它。 见证数据不需要发送到所有节点,也不需要所有节点存储在硬盘上。

l 签名验证优化

Segwit升级签名函数(CHECKSIG、CHECKMULTISIG等)降低了算法的计算复杂度。 在引入隔离见证之前,用于生成签名的算法需要进行大量与交易规模成正比的哈希运算。 O(n2)的签名操作次数增加了数据哈希计算,给所有验证签名的节点带来了很大的计算负担。 在引入隔离见证之后,算法的变化将复杂度降低到 O(n2)。

l 离线签名改进

隔离见证签名包含被签名的哈希中每个输入引用的值(数量)。 以前,离线签名设备(例如硬件钱包)必须在签署交易之前验证每个输入的金额。 这通常是通过将有关先前交易的大量数据流作为输入来完成的。 由于金额现在是已签名承诺哈希的一部分,因此离线方式不需要先前的交易。 如果金额不匹配(被入侵的在线系统错误报告),则签名无效。

在P2PSH的例子中,穆罕默德的公司使用P2SH来表达多重签名脚本。 支付给穆罕默德公司的款项被编码成一个锁定脚本,如下所示:

P2SH 输出脚本示例:

HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e EQUAL

此 P2SH 脚本引用赎回脚本的哈希值,该脚本定义了“2 of 3”多重签名要求以花费资金。 为了使用该输出,Muhammad 的公司将提供此兑换脚本(其哈希与 P2SH 输出中的脚本哈希相匹配),以及满足该兑换脚本所需的签名,所有这些都在交易输出中:

显示正在使用的 P2SH 输出的解码交易:

[...]“Vin” : ["txid": "abcdef12345...","vout": 0, "scriptSig": “  <2 PubA PubB PubC PubD PubE 5 CHECKMULTISIG>”,]

现在,让我们看看如何将整个示例升级为隔离见证。 如果 Muhammad 的客户使用符合 SegWit 的钱包,他们将进行支付,创建一个“Pay to Script Hash”(P2WSH)输出,如下所示:

P2WSH 输出脚本示例:

0 9592d601848d04b172905e0ddb0adde59f1590f1e553ffc81ddc4b0ed927dd73

同样,就像 P2WPKH 示例一样,您可以看到隔离见证等效脚本要简单得多,省略了您在 P2SH 脚本中看到的各种脚本运算符。 相反,隔离见证程序仅由压入堆栈的两个值组成:见证版本 (0) 和赎回脚本的 32 字节哈希。

提示 虽然 P2SH 使用 20 字节的 RIPEMD160(SHA256(script)) 哈希值,但 P2WSH 见证程序使用 32 字节的 SHA256(script) 哈希值。 这种差异是在选择哈希算法时有意为之的,用于通过哈希值长度区分两种类型的见证程序(P2WPKH 和 P2WSH),并为 P2WSH(128 位而不是 80 位 P2SH)提供更多的鲁棒性. 安全性强。

Muhammad 的公司可以通过提供正确的赎回脚本和足够的签名来满足和使用 P2WSH 输出。 兑换脚本和签名作为见证数据的一部分与此支出交易隔离开来。 在交易输入中,Muhammad 的钱包将放置一个空的 scriptSig:

解码交易显示 P2WSH 输出与隔离见证数据一起使用:

[...]“Vin” : ["txid": "abcdef12345...","vout": 0, "scriptSig":“”,][...]“witness”: “  <2 PubA PubB PubC PubD PubE 5 CHECKMULTISIG>”[…]

我们可以看到witness数据被放入Witness中,scriptSig为空。

节点可以在验证签名后删除这些见证数据,或者在进行简单的支付验证时完全忽略它。 见证数据不需要发送到所有节点,也不需要所有节点存储在硬盘上。

4.总结

多重签名很强大比特币脚本csdn,但是复杂的锁定脚本数据量大,使用起来还是不方便。

P2SH 就是为了解决这个实际问题而引入的,它旨在让复杂脚本的使用变得像直接向比特币地址支付一样简单。 在 P2SH 支付中,复杂的锁定脚本被哈希值取代。

P2SH 的解锁脚本通常是总交易量的重要贡献者,更复杂的脚本通常非常大,例如用于多重签名或支付通道的脚本。

P2WSH 通过将解锁脚本(见证数据)移出交易来提高比特币的可扩展性,同时增加区块大小并降低交易费用。

5. 参考资料

精通比特币(第二版)

【BitTribeLab】BitTribeLab是一个全球创新实验室(节点)网络,以构建去中心化的未来信息基础设施和去中心化金融(Defi)新世界为愿景,邀请思想家、科幻爱好者、技术极客、开源软件开发者还有更多的人加入。