其实我们能够这样看待比特币的买卖:『买卖的发起者赏格若干比特币,在网络上贴出了一到数学题,谁解出了这道数学题,赏格就归谁了』。 顺着这个思路,Alice对Bob的转账能够了解为『Alice把一道只有Bob才能解开的数学题发到网络上,Bob解出题并拿走了赏格』。那么,每个买卖数据中都会出现的『脚本』便是题宽和,『脚本语言』便是用来描绘题宽和的工具。


『输入脚本』和『输出脚本』

在这里我们先讨论单输入单输出的比特币买卖,由于这样描绘起来更方便且不影响对『脚本』的了解。
9c50cee8d50e273100987bb12ec46208cb04a1d5b68c9bea84fd4a04854b5eb1这是一个单输入单输出买卖,看下我们要关注的数据:

Hash:

9c50cee8d50e273100987bb12ec46208cb04a1d5b68c9bea84fd4a04854b5eb1

输入买卖:

前导输入的Hash:

437b95ae15f87c7a8ab4f51db5d3c877b972ef92f26fbc6d3c4663d1bc750149

输入脚本 scriptSig:

3045022100efe12e2584bbd346bccfe67fd50a54191e4f45f945e3853658284358d9c062ad02200121e00b6297c0874650d00b786971f5b4601e32b3f81afa9f9f8108e93c752201038b29d4fbbd12619d45c84c83cb4330337ab1b1a3737250f29cec679d7551148a

输出买卖:

转账值:

0.05010000 btc

输出脚本 scriptPubKey:

OP_DUP OP_HASH160 be10f0a78f5ac63e8746f7f2e62a5663eed05788 OP_EQUALVERIFY OP_CHECKSIG

假设Alice是转账发送者,Bob是接受者。那么『输入买卖』表明晰Alice要动用的比特币的来源,『输出买卖』表明晰Alice要转账的数额和转账目标——Bob。那么,你可能要问,数据中的『输入脚本』和『输出脚本』是不是便是题宽和?对了一半!

在Bitcoin Wiki中说到:

原先发送币的一方,操控脚本运转,以便比特币鄙人一个买卖中运用。想花掉币的另一方必须把以前记载的运转为真的脚本,放到输入区。

换句话说,在一个买卖中,『输出脚本』是数学题,『输入脚本』是题解,但不是这道数学题的题解。我开端看Wiki的时分,在这里遇到了一些妨碍,无法了解『输入脚本』和『输出脚本』的联系。但是在考虑买卖间的联系后,就理解了。

假设有这么一系列买卖:

1. 上图的三个买卖都是单输入单输出买卖
2. 每个『输入买卖』『输出买卖』中,都包括对应的『脚本』
3.买卖a,Alice转账给Bob;买卖b,Bob转账给Carol;买卖c,Carol转账给Dave
4. 当前买卖的『输入』都引证前一个买卖的『输出』,如买卖b的『输入』引证买卖a的『输出』

按照之前的说法,买卖a中的『输出脚本』便是Alice为Bob出的数学题。那么,Bob想要引证买卖a『输出买卖』的比特币,就要解开这道数学题。题解是在买卖b的『输入脚本』里给出的!Bob解开了这道题,获得了奖金,然后在买卖b中为Carol出一道数学题,等候Carol来解...

所以说,下图中相同颜色的『输出』和『输入』才是一对题宽和:


脚本语言

Bitcoin Wiki给出的对脚本的解释:

比特币在买卖中运用脚本体系,与FORTH(一种编译语言)相同,脚本是简略的、基于仓库的、而且从左向右处理,它特意设计成非图灵完好,没有LOOP语句。

要了解比特币脚本,先要了解『仓库』,这是一个后进先出(Last In First Out )的容器,脚本体系对数据的操作都是通过它完成的。比特币脚本体系中有两个仓库:主仓库和副仓库,一般来说首要运用主仓库。举几个简略的例子,看下指令是怎么对仓库操作的(完好的指令集在Wiki里能够找到):

  • 常数入栈:把一段常数压入到仓库中,这个常数成为了栈顶元素

  • OP_DUP:仿制栈顶元素

  • OP_EQUALVERIFY:查看栈顶两个元素是否持平


规范买卖脚本

也便是P2PKH(Pay To Public Key Hash),我们常用的转账方式。Alice在转账给Bob的时分,『输出买卖』中给出了Bob的『钱包地址』(等价于『公钥哈希』);当Bob想要转账给Carol的时分,他要证明自己具有这个『钱包地址』对应的『私钥』,所以在『输入买卖』中给出了自己的『公钥』以及运用『私钥』对买卖的签名。看个实例:
* 买卖a:9c50cee8d50e273100987bb12ec46208cb04a1d5b68c9bea84fd4a04854b5eb1
* 买卖b:62fadb313b74854a818de4b4c0dc2e2049282b28ec88091a9497321203fb016e

买卖b中有一个『输入买卖』引证了买卖a的『输出买卖』,它们的脚本是一对题与解:
题:买卖a的『输出脚本』,若干个脚本指令和转账接收方的『公钥哈希』

OP_DUP OP_HASH160 be10f0a78f5ac63e8746f7f2e62a5663eed05788 OP_EQUALVERIFY OP_CHECKSIG

解:买卖b的『输入脚本』,这么一长串只是两个元素,『签名』和『公钥』(sig & pubkey)

3046022100ba1427639c9f67f2ca1088d0140318a98cb1e84f604dc90ae00ed7a5f9c61cab02210094233d018f2f014a5864c9e0795f13735780cafd51b950f503534a6af246aca301 03a63ab88e75116b313c6de384496328df2656156b8ac48c75505cd20a4890f5ab

下面来看下这两段脚本是怎么履行,来完成『解题』进程的。

  1. 首先履行的是『输入脚本』。由于脚本是从左向右履行的,那么先入栈的是『签名』,随后是『公钥』

  2. 接着,履行的是『输出脚本』。从左向右履行,第一个指令是OP_DUP——仿制栈顶元素

  3. OP_HASH160——核算栈顶元素Hash,得到pubkeyhash

  4. 将『输出脚本』中的『公钥哈希』入栈,为了和前面核算得到的哈希区别,称它为pubkeyhash'

  5. OP_EQUALVERIFY——查看栈顶前两元素是否持平,假如持平继续履行,不然中止履行,回来失利

  6. OP_CHECKSIG——运用栈顶前两元素履行签名校验操作,假如持平,回来成功,不然回来失利

这样一串指令履行下来,就能够验证这道数学题是否做对了,也便是说验明晰想要花费『钱包地址』中比特币的人是否具有对应的『私钥』。上面的履行进程是能够在脚本模拟器中履行的,能够看到每一步履行的状况,感兴趣的童鞋能够尝试一下。

其实除了规范的P2PKH买卖脚本,还有P2SH的Multi-Sig脚本以及真实的『解谜买卖』脚本,我们能够在今后接着讨论。

作者:汪海波Hyper
Blog建设中,欢迎拜访
2014-11-26


参阅

[1] 申屠芳华(我看比特币),【比特币脚本】
[2] Bitcoin Wiki,【Script】

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注