摘要
这个BIP描述了比特币脚本系统中一个新的标准交易类型,定义了额外的验证规则,但是只能适用于新的交易。
动机
pay-to-script-hash脚本类型的目的是将构建交易的成本从发送交易方转嫁到赎回方。
它的好处是允许交易发起者能够构建各种交易,不管多么复杂,只需要使用20字节固定长度的哈希,这个足够短的hash能够通过扫描二维码或者简单的复制粘贴完成。
说明
一个新的交易类型,能够被转发并打包入块,它被这样定义:
OP_HASH160 [20-byte-hash-value] OP_EQUAL
[20-byte-hash-value]应该被操作码(0x14)push到栈上,这个操作码紧跟着这个20字节的hash。这个新的交易通过一个标准的解锁脚本被赎回:
...signatures... {serialized script}
如果一个交易序列化的脚本(也成为赎回脚本)是其本身, 也就是其他标准交易类型的一种,那么这个交易就被认为是唯一标准的,能够赎回pay-to-script交易的输出。
当在转发交易或将交易打包入块之前,这些交易输出的验证规则如下:
如果在解锁脚本中存在任何的push data操作码以外的操作码,验证失败。
初始化的栈空间通过签名和序列化脚本创建,如果序列化的脚本hash和outpoint中的hash不匹配时,验证立即失败。
序列化脚本从初始栈弹出,使用弹出的栈和反序列化脚本作为锁定脚本,这个交易被认为是有效的。
当验证一个交易时,这些新的规则只有在时间戳大于等于1333238400(2012年4月1日)才会被使用。一个早于1333238400时间戳的交易,使用新的交易验证规则会验证失败。旧的交易在在旧的交易验证规则下一定是有效的(查看向后兼容性的详细内容)。
举例,含有锁定脚本以及与其对应的只有一个签名的解锁脚本的交易:
scriptSig: [signature] {[pubkey] OP_CHECKSIG}
scriptPubKey: OP_HASH160 [20-byte-hash of {[pubkey] OP_CHECKSIG} ] OP_EQUAL
序列化脚本中的签名数需要低于一个区块20000个的最大限制,如下:
不管它们是否被评估,
OP_CHECKSIG
和OP_CHECKSIGVERIFY
被认为是一个签名操作。不管它们是否被评估,
OP_CHECKMULTISIG
和OP_CHECKMULTISIGVERIFY
会在OP_1
到OP_16
操作码前,被认为1~16个签名操作。所有其他的
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签名的区块,当其他节点在验证当前这个区块的同时,这个不诚实的节点已经领先计算下一个区块。
旧的实现存在一次确认攻击,但是在实践中这种攻击是非常昂贵和困难的。攻击如下:
攻击者创建一个P2SH交易,这个交易被旧版本的软件认为是有效的,但是新的软件验证为非法的,攻击者使用这个交易给他们自己发送一些币。
攻击者然后创建一个标准的交易,来花费这个P2SH交易,并支付给运行旧软件的受害者。
攻击者创建一个区块,并包含这两个交易。
如果受害者接受一次确认支付,由于其他节点验证该区块是非法的,因此覆盖了这个非法的区块,然而攻击者已经获胜了。
然而这种攻击代价是十分昂贵的,首先攻击者要创建一个区块,而其他网络节点会认为其无效,创建一个区块本身也是非常困难的。因此,用户不应该接受金额非常大的一次确认交易。
向后兼容
这些交易对于旧版本的软件来说是非标准的,它们不会转发这些交易,也不会将这些交易打包入块。
旧版本的软件在验证区块(由支持该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字节。
参考实现
https://gist.github.com/gavinandresen/3966071
其它资料
参考
引用
原文链接: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
本文由 Copernicus团队 戚帅 翻译,转载无需授权。