打字猴:1.70386539e+09
1703865390 首先,我们复制指令OP_DUP,这一步仅仅是将堆栈最上层的公钥复制,并置于堆栈最上层;下一个指令是OP_HASH160,该指令取得堆栈最上层的数据,并计算其哈希值,然后将结果再堆到堆栈最上层。当指令执行完成后,我们将堆栈最上层的公钥替换成了公钥的哈希值。
1703865391
1703865392
1703865393
1703865394
1703865395 图3.6 比特币脚本的执行堆栈状态图
1703865396
1703865397 注:图中底部列出了相对应的指令:尖括号里的是数据指令,以OP开头的是工作码指令,指令上方对应的是指令执行之后的堆栈状态。
1703865398
1703865399 接下来,我们还要在堆栈顶层再推送一些数据:此笔交易发送者指定的公钥的哈希值,以及对应的私钥,这样才可完成签名,取得资金。此时,堆栈顶部有两个数值,一个是发送者指定的公钥的哈希值,另一个是接收者想要取得资金时提交的公钥的哈希值。
1703865400
1703865401 这个时候,我们就要执行EQUALVERIFY命令了,这个命令是用来检查堆栈顶部两个数值是否相等的。如果不相等,就会抛出一个失败信号,并且停止执行脚本。不过现在我们假设其相等,也就代表着接收者使用的是正确的公钥。这条指令会移除堆栈顶部的两条数据,这时,堆栈还剩下两个数据:公钥以及签名。
1703865402
1703865403 我们已经证实接收者使用的公钥确实就是交易里指定的公钥,但现在我们必须证实这个签名是真的。这时,使用OP_CHECKSIG指令即可。这里我们可以看出比特币的脚本语言虽然简单,但很强大。它只用“OP_CHECKSIG”就能实现一个很复杂的事情:移除堆栈里两个数值,然后用公钥来证实整个交易的签名是真的。
1703865404
1703865405 但这里的签名究竟是对什么的签名?签名函数的输入是什么?实际上,在比特币中,我们只可以对一个事情进行签名——就是整个交易。所以,CHECKSIG指令从堆栈中取出两个数据(公钥以及签名),并验证签名对于整个交易(使用对应公钥发起的交易)来说是有效的。现在我们完成了所有的指令,堆栈里面什么也不剩。假设没有碰到任何差错的话,这个脚本的输出就是一个“真”表示这个交易是正当有效的。
1703865406
1703865407 实际情况
1703865408
1703865409 理论上来讲,通过脚本,我们可以随意地为比特币支付设定条件。当然,从2015年的情况看,这些特性也并不太常用到。如果我们回顾比特币历史中曾经实际用到的脚本,绝大多数的比特币使用的脚本都非常基础,像前文的例子一样:指定一个公钥,然后通过验证签名来使用这个币。
1703865410
1703865411 当然,实际中也会使用一些其他指令,比如MULTISIG,还有一种支付给脚本的哈希值(Pay-to-script-hash,简称P2SH,我们很快会谈到)等,但除此之外,平时常用的指令真不多,因为每个节点都有一份标准脚本的白名单,它们会拒绝接受不在名单上的脚本。这倒不是说无法运行其他脚本,只是使用起来比较麻烦。事实上这样的安排也很巧妙,我们会在谈论比特币点对点网络的时候再进行描述。
1703865412
1703865413 销毁证明
1703865414
1703865415 销毁证明(proof of burn)脚本,用于销毁比特币(即防止资金被赎回)。如果交易代码的运行结果是将比特币转到“销毁证明”脚本,那么这笔比特币将被销毁。实际应用中主要是用来引导客户使用其他数字货币系统,即将比特币销毁,以便获得另一个数字货币系统发行的新币。我们会在第10章展开叙述。销毁证明脚本使用起来非常简便:使用OP_RETURN脚本来抛出错误;不论之前指令的运行结果是什么,OP_RETURN指令总会被执行,并相应抛出一个错误,脚本返回一个“错误”(false)值。
1703865416
1703865417 由于OP_RETURN以抛出错误的形式结束脚本,其后的所有指令都不会执行。利用这个特性,我们可以往脚本中植入任意信息,这些信息也将被存储在区块链中。假如你想通过署名或者盖时间戳的方式来证明你在某个时候知道某件事情,就可以发起一笔极小额的比特币交易,在脚本中加入上述信息,并使用销毁证明脚本将币销毁,这样就可以将信息永久地存储在区块链上。
1703865418
1703865419 支付给脚本的哈希值
1703865420
1703865421 如前文所述,比特币的工作机制要求币的发送者必须在交易时明确指定脚本。这种机制有时候不太适用:假如你在网店看中了一件商品并打算下单,你会问卖家“请把付款地址告诉我,我可以付款了”,但如果卖家使用了多重签名地址(MULTISIG),那他会说“嘿,我们用了多重签名地址,你需要支付给一个脚本地址,而不是一个简单的地址”,但你会说“我不知道怎么弄,这太复杂了,我只会支付给简单的地址”。
1703865422
1703865423 比特币用了一种很聪明的办法来解决这个问题,不仅可以实现多重签名地址支付,而且还可以实现复杂的资金监管规则。比特币使用的办法是:收款方告诉付款方“请把比特币支付给某个脚本地址,脚本的哈希值是××,在取款的时候,我会提供上述哈希值对应的脚本,同时,提供数据通过脚本的验证”,而不是“请把比特币支付给某个公钥,公钥的哈希值是××”。付款方通过P2SH即可实现上述交易。
1703865424
1703865425 需要说明的是,P2SH脚本只是对堆栈最顶层的数据进行哈希运算,核验运算结果是否与给定的哈希值一致,核验通过后,再执行一步特殊的核验:将堆栈最顶层的数据重新解读为一系列指令,然后将其作为脚本运行一次,此时,堆栈中的其他数据作为脚本的输入值。
1703865426
1703865427 要做到P2SH还是有点复杂的,因为P2SH不是比特币的原始设计,是后来加上去的。它解决了两个重要的问题:让付款方的支付工作简单化,收款方只需告诉付款方一个哈希值即可。在我们上面的例子中,你不再需要去关心商家到底用哪种地址,是否用了多重签名,因为这只是商家在支取这笔款项时需要考虑的事情。
1703865428
1703865429 P2SH还实现了效率上的提升:矿工的工作是追踪那些还没有被消费掉的输出脚本。采用P2SH的输出脚本会变得很小——它们只不过是个哈希值而已。所有的复杂性都被放在输入脚本中了。
1703865430
1703865431 [1]图灵是第二次世界大战时英国数学家,密码学家。他破译了纳粹的密码机“谜”,为盟军取得第二次世界大战胜利做出重大贡献,美国好莱坞以此题材拍了一部电影《模仿游戏》。图灵完备的意思是语言有能力随意地执行强大的函数。——译者注
1703865432
1703865433
1703865434
1703865435
1703865436 区块链技术驱动金融:数字货币与智能合约技术 [:1703863921]
1703865437 区块链技术驱动金融:数字货币与智能合约技术 3.3 比特币脚本的应用
1703865438
1703865439 现在我们已经明白了比特币脚本的工作机制,接下来我们看一下比特币脚本语言的一些强大应用。你立刻就能明白,比特币将指定公钥变成复杂地指定脚本,是有实际意义的。
[ 上一页 ]  [ :1.70386539e+09 ]  [ 下一页 ]