BIP16 P2SH交易脚本

动机

 

pay-to-script-hash脚本类型的目的是将构建交易的成本从发送交易方转嫁到赎回方。

它的好处是允许交易发起者能够构建各种交易,不管多么复杂,只需要使用20字节固定长度的哈希,这个足够短的hash能够通过扫描二维码或者简单的复制粘贴完成。

 

说明

 

一个新的交易类型,能够被转发并打包入块,它被这样定义:

OP_HASH160 [20-byte-hash-value] OP_EQUAL

[20-byte-hash-value]应该被操作码(0×14)push到栈上,这个操作码紧跟着这个20字节的hash。这个新的交易通过一个标准的解锁脚本被赎回:

...signatures... {serialized script}

如果一个交易序列化的脚本(也成为赎回脚本)是其本身, 也就是其他标准交易类型的一种,那么这个交易就被认为是唯一标准的,能够赎回pay-to-script交易的输出。

当在转发交易或将交易打包入块之前,这些交易输出的验证规则如下:

  1. 如果在解锁脚本中存在任何的push data操作码以外的操作码,验证失败。
  2. 初始化的栈空间通过签名和序列化脚本创建,如果序列化的脚本hash和outpoint中的hash不匹配时,验证立即失败。
  3. 序列化脚本从初始栈弹出,使用弹出的栈和反序列化脚本作为锁定脚本,这个交易被认为是有效的。

当验证一个交易时,这些新的规则只有在时间戳大于等于1333238400(2012年4月1日)才会被使用。一个早于1333238400时间戳的交易,使用新的交易验证规则会验证失败。旧的交易在在旧的交易验证规则下一定是有效的(查看向后兼容性的详细内容)。

举例,含有锁定脚本以及与其对应的只有一个签名的解锁脚本的交易:

scriptSig: [signature] {[pubkey] OP_CHECKSIG}
 scriptPubKey: OP_HASH160 [20-byte-hash of {[pubkey] OP_CHECKSIG} ] OP_EQUAL

序列化脚本中的签名数需要低于一个区块20000个的最大限制,如下:

  1. 不管它们是否被评估,OP_CHECKSIG 和 OP_CHECKSIGVERIFY 被认为是一个签名操作。
  2. 不管它们是否被评估,OP_CHECKMULTISIG 和 OP_CHECKMULTISIGVERIFY 会在 OP_1 到 OP_16 操作码前,被认为1~16个签名操作。
  3. 所有其他的 OP_CHECKMULTISIG 和 OP_CHECKMULTISIGVERIFY 被认为是20个签名操作。

例如:

+3签名操作:

{2 [pubkey1] [pubkey2] [pubkey3] 3 OP_CHECKMULTISIG}

+22 signature operations

{OP_CHECKSIG OP_IF OP_CHECKSIGVERIFY OP_ELSE OP_CHECKMULTISIGVERIFY OP_ENDIF}

 

基本原理

 

这个BIP代替了BIP12, BIP12试图通过新的交易码 OP_EVAL 完成这个BIP的所有事情并且更多。

这个BIP(和BIP13,描述P2SH地址类型)的动机存在一些争议;很多人认为它是没必要的,复杂的多重签名交易类型可以简单的通过发起者完成序列化脚本来支持。但作者认为此这个BIP已经做到了最小化改变,来促使商家、交易所以及其他软件支持多重签名,将资金发送到base58编码的20字节的比特币地址。

虽然识别一个特殊的锁定脚本格式,并执行额外的验证,这是非常令人厌恶的。但是一直认为要么实现越来越复杂,要么以一种非常危险的方式扩展表达语言的能力。

这个签名操作的计数规则趋向于通过静态扫描序列化脚本能够简单快速的被实现。比特币规定了一个区块所能包含的最大签名数量,防止恶意的DOS攻击。假如没有这个限制,一个不诚实的旷工可能广播一个包含数十万个ECDSA签名的区块,当其他节点在验证当前这个区块的同时,这个不诚实的节点已经领先计算下一个区块。

旧的实现存在一次确认攻击,但是在实践中这种攻击是非常昂贵和困难的。攻击如下:

  1. 攻击者创建一个P2SH交易,这个交易被旧版本的软件认为是有效的,但是新的软件验证为非法的,攻击者使用这个交易给他们自己发送一些币。
  2. 攻击者然后创建一个标准的交易,来花费这个P2SH交易,并支付给运行旧软件的受害者。
  3. 攻击者创建一个区块,并包含这两个交易。
  4. 如果受害者接受一次确认支付,由于其他节点验证该区块是非法的,因此覆盖了这个非法的区块,然而攻击者已经获胜了。

然而这种攻击代价是十分昂贵的,首先攻击者要创建一个区块,而其他网络节点会认为其无效,创建一个区块本身也是非常困难的。因此,用户不应该接受金额非常大的一次确认交易。

 

向后兼容

 

这些交易对于旧版本的软件来说是非标准的,它们不会转发这些交易,也不会将这些交易打包入块。

旧版本的软件在验证区块(由支持该BIP的新软件创建)将会验证序列化脚本hash的一致性,不会再做额外的验证。

为了避免区块链通过恶意的P2SH交易而被分割,需要处理下面的这种情况:

一个P2SH交易对于新版本软件是无效的,而对于旧版本软件是有效的。

为了顺利的完成升级并确保不会发生永久的区块链分裂,需要超过50%的旷工同时从旧版本验证规则变成新版本验证规则,并支持新交易类型的完整验证规则。

为了判断是否超过50%的算力支持该BIP,旷工被要求升级软件,并在他们创建区块创币交易输入中加入”/P2SH/“字符串。

在2012年2月1日,区块链将会检查在过去7天内支持P2SH交易的区块数量。如果550个或更多的创币交易中包含”/P2SH/“,那么时间戳在2012年2月15日00:00:00 GMT之后的所有区块将完全支持P2SH交易。在一个星期内,大约有1000个区块被创建。因此,550,大约是55%的全网节点支持该新特性。

如果大部分算力不支持这种新的验证规则,该BIP将会被延期,如果明确表明大部分算力将永远不会支持该提议,那么该BIP将会被取消。

 

序列化脚本的520字节限制

 

作为向后兼容要求的结果,序列化脚本本身受到与任何其他 PUSHDATA 操作相同的规则,包括大于520字节的数据不会被push到栈中。因此,如果赎回脚本长度大于520字节,则不可能花费该P2SH交易。例如,当 OP_CHECKMULTISIG 操作码本身接收到多达20个pubkey时,使用33字节压缩的公钥,只能花费最多包含15个pubkey的P2SH赎回脚本:3个字节+ 15个pubkeys * 34个字节/pubkey = 513字节。

一.在bitcoin bips历史上先有M-of-N Transaction(bip-11),然后才有Pay To Script Hash(bip-16)(简称P2SH),首先记住顺序很重要

二.P2SH的含义

1.比特币的关键是认证,A发送给B,B必须提供相关证明才可以发送币给C。

2.刚开始的时候,认证是通过私钥,B提供对应地址的私钥的签名信息来表明币属于自己所有

认证方法如下

A->B : scriptPubKey: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG

B->C :scriptSig: <签名> <公钥>

认证是通过栈来实现的,先把scriptSig压栈,然后取scriptPubKey中元素,是数据就压栈,是操作符就执行对应操作,具体过程参见(https://en.bitcoin.it/wiki/Script#Standard_Transaction_to_Bitcoin_address_.28pay-to-pubkey-hash.29)

3.上述方法简称P2PK(pay to public key)

4.然后Gavin Andresen在bip16提出一种P2SH(pay to Script Hash)方法,主要目的有两个,一是容许发送者构造丰富的交易类型,二是将字节从A->B的output转移到B->C的input(A->B的output script中将是固定长度)

理解这类交易类似先参见(https://en.bitcoin.it/wiki/Script#Transaction_puzzle)介绍

scriptPubKey: OP_HASH 6fe28c0ab6f1b372c1a6 OP_EQUAL

我们可以理解成解数学中的难题,hash(x) = 6fe28c0ab6f1b372c1a6 我们只是提供一个x满足这个条件,就可以证明我可以花费这笔钱了。

P2SH也是类似

scriptPubKey: OP_HASH160 3fe28c0ab6f1b372c1a6 OP_EQUAL

这里3fe28c0ab6f1b372c1a6不是简单的一个数字的hash,而是一段script的hash(简称redeemScript)

scriptPubKey:OP_HASH160 hash(redeemScript) OP_EQUAL

我们可以理解成只要你提供了一段script,它的二进制hash和目标匹配,那么你就可以花费这笔钱了

三.多重签名的实现

按照一中提到的说明顺序,其实比特币中实现多重签名有两种方法

a.原始的方法(bip-11)

scriptPubKey : m {pubkey}...{pubkey} n OP_CHECKMULTISIG

scriptSig : OP_0 ...signatures...

实例:https://blockchain.info/tx/09dd94f2c85262173da87a745a459007bb1eed6eeb6bfa238a0cd91a16cf7790

b.用P2SH来实现

首先说明P2SH的认证过程

scriptSig: [signature] {[pubkey] OP_CHECKSIG}

scriptPubKey: OP_HASH160 [20-byte-hash of {[pubkey] OP_CHECKSIG} ] OP_EQUAL

这里{[pubkey] OP_CHECKSIG}就是我们提到redeemScript代码

它的栈认证过程和之前稍有不同

栈内容变化如下

[signature],

[signature], {[pubkey] OP_CHECKSIG}

[signature], {[pubkey] OP_CHECKSIG}, OP_HASH160

[signature], hash160({[pubkey] OP_CHECKSIG}) ;保存的是hash的结果

[signature], hash160({[pubkey] OP_CHECKSIG}), [20-byte-hash of {[pubkey] OP_CHECKSIG} ]

[signature], hash160({[pubkey] OP_CHECKSIG}), [20-byte-hash of {[pubkey] OP_CHECKSIG} ], OP_EQUAL

[signature], [pubkey] OP_CHECKSIG (看到没有,就是这里,需要将redeemScript重新压栈)

以下的执行过程就和a中相同了

实例https://blockchain.info/tx/3c9018e8d5615c306d72397f8f5eef44308c98fb576a88e030c25456b4f3a7ac

总结

1.首先P2SH和MultiSig是完全不同两码事,很多文章将P2SH表述成MultiSig,这是不恰当的

只不过现在可以用P2SH来实现MultiSig,好像前不久刚测试成功了

2.比特币的关键是认证,刚开始中本聪提供用私钥认证,后来人发明了用hash(redeemScript)认证.

3.P2SH丰富了交易类似,简单易扩展


你可能感兴趣的:(比特币)