解读比特币的可扩展性方案:隔离见证( 二 )


案例
Pay-to-Witness-Public-Key-Hash
我们用例子来说明一下隔离见证会如何改变交易的数据结构 。 从标准的Pay-to-Public-Key-Hash(P2PKH)交易类型开始 。
我们感兴趣的部分是输出 , 尤其是其“scriptPubKey”字段(锁定脚本字段) 。 我们先考虑一种标准的锁定脚本:
而隔离见证之后的锁定脚本如下所示:
如你所见 , 隔离见证的输出比传统类型的输出要简单很多:只有两个值会被推入脚本执行栈中 。 如我们上面说得 , 旧版本的比特币客户端会以为这个输出是掉在地上的钱——无需提供签名就能花费这个输出 。 不过 , 新的客户端会将第一个数字解释为版本号 , 而第二个则对应着一个锁定脚本(witness程序) 。 在现实中 , 只有压缩公钥(compressedpublickey)的哈希值可以用在这里 。 这一点我们后面再说 。
再来看看这个输出被花费时的情形 。 传统交易的输出在花费时的数据结构如下:
解读比特币的可扩展性方案:隔离见证

但是 , 在花费一个隔离见证输出的时候 , 交易的scriptSig将为空 , 而所有的签名都会放到一个专门的地方:
解读比特币的可扩展性方案:隔离见证

警告
虽然传统的客户端可以处理隔离见证的交易(再次提醒 , 他们会把这些输出当成人人都可以花的钱) , 但他们自己没法花这些钱:旧型的钱包可能会尝试用空签名来花用一个隔离见证的输出 , 但这笔交易在现实中是无效的(更新之后的节点不会允许这样的交易上链) 。 这就意味着 , 发送者必须知道接受方的钱包支不支持隔离见证 , 这样才能为之创建合适类型的输出 。
由BIP143定义 , 隔离见证的输出应该用压缩公钥的哈希值来创建 。 如果你用的是传统类型的地址或者非压缩公钥的哈希值 , 这个输出将变得不可用(你的币会锁死) 。
Pay-to-Witness-Script-Hash
另一个关键的交易类型是P2SH 。 它让交易可以发送给脚本的哈希值(而非公钥的哈希值 , 也即比特币地址) 。 要花费P2SH交易的输出 , 花费者需要提供一个脚本(叫做“赎回脚本”) , 其哈希值应该与UTXO中的脚本哈希值匹配 , 并基于这个脚本提供签名/口令/别的东西 。 这个用法可以把解锁脚本保护起来 , 让发送者无从知晓一个地址的内容 , 并且也能节约空间:举个例子 , 一个多签名钱包的锁定脚本可能非常长 , 这样我们就必须把整个锁保存起来;有了P2SH可以只保存一个哈希值 。
假设现在有一个需要提供5个私钥中的2个的签名才能使用的多签名钱包 。 如果你使用传统的交易 , P2SH交易输出的锁定脚本将如下:
要花它的时候 , 花费的人(也是上一笔交易的接收方)需要提供一个赎回脚本 , 这个脚本定义了花费条件(多签名 , 2-5) , 还有两个签名 。 所有这些都要放在交易的输入中:
解读比特币的可扩展性方案:隔离见证

再来看看使用隔离见证后的发送者和接收者 。 输出的锁定脚本如下:
就像P2PKH交易一样 , 这个输出的脚本也变得更简单 。 第一个数值表示版本号 , 第二个是对应于赎回脚本(witness程序)的SHA256哈希值(32位) 。 使用这个函数某种意义上是为了用长度来区分P2WPKH的见证程序以及P2WSH的见证程序(32字节的SHA256哈希值vs.RIPEMD160(SHA256(script))) 。
使用这一输出的交易如下所示:
解读比特币的可扩展性方案:隔离见证

在P2SH中嵌入隔离见证
我们已经看到 , 使用隔离见证是有好处的 。 不过 , 上面的例子只对发送者和接收者都有升级软件的情形才适用 。 但现实并不总是如此 。 考虑这样一种情形: