1703865310
图3.2 与比特币类似的基于交易的账本
1703865311
1703865312
地址转换。在这个例子里,为什么爱丽丝要把币转给自己呢?事实上比特币就像财奴币中描述的币一样,一个交易中输出的币,要么在另一个交易中被完全消费掉,要么就一个都不被消费,不存在只消费部分的情况。爱丽丝只需付给鲍勃17个币,但爱丽丝在上一交易中实际获得了25个币,为了把这些币全部消费掉,她必须再转给自己8个币。这8个币可以转到另外一个地址(不同于交易1中获得25个币的地址),但前提是该地址为爱丽丝所有,这就叫地址转换。
1703865313
1703865314
有效验证。当一个新的交易被加入总账,它的有效性是否容易被验证?在这个例子里,我们要核查一下爱丽丝引用的交易输出,确认她确实有25个币没有被花费掉。因为我们使用了哈希指针,所以核查很快。为了确认这25个币没有被花掉,我们只需从爱丽丝所引用的交易开始,一直核查到账本上最新记录的交易为止即可——而不需要从账本建立之初的交易开始核查。而且,这种方法也不需要增加额外的数据结构(当然,我们将会看到,加入新的数据结构将进一步提高速度)。
1703865315
1703865316
资金合并。和财奴币一样,比特币交易可能有许多输入与输出,资金分隔与合并也很容易。假如鲍勃在两笔不同的交易中分别收到17个币和2个币,现在他想把这两笔钱合并起来花掉,这很容易,他只需发起一个交易,交易里有两个输入和一个输出,输出的地址是他自己的地址,这样,鲍勃就把两个交易合二为一了。
1703865317
1703865318
共同支付。同样地,共同支付也很容易做到。如果卡罗尔和鲍勃想要共同支付给戴维,他们可以发起一个交易,交易里也有两个输入和一个输出,唯一不同在于,两个输入所引用的“上一笔交易”的输出地址不同,因此,这笔交易需要两个签名:卡罗尔的和鲍勃的。
1703865319
1703865320
交易语法。比特币交易涉及的概念就是上面这些。我们再来看看比特币交易在底层是如何实现的。实际上,比特币在网络上传输的数据结构都是一串字符,图3.3显示了一个真实的程序,经过编译就会变成供机器执行的二进制代码了。
1703865321
1703865322
1703865323
1703865324
1703865325
图3.3 一个真实的比特币交易程序段
1703865326
1703865327
从图3.3可以看到,一个比特币交易分成三部分:元数据、一系列的输入和一系列的输出。
1703865328
1703865329
● 元数据。这里存放一些内部处理的信息:包含这笔交易的规模、输入的数量、输出的数量,还有此笔交易的哈希值,也就是这个交易独一无二的ID。我们可以用哈希指针指向这个ID。最后还有一个“锁定时间”(lock_time),我们后面会谈到。
1703865330
1703865331
● 输入。所有输入排成一个序列,每个输入的格式都是一样的。输入需要明确说明之前一笔交易的某个输出,因此它包括之前那笔交易的哈希值,使其成为指向那个特定交易的哈希指针。这个输入部分同时包括之前交易输出的索引和一个签名:我们必须有签名来证明我们有资格去支配这笔比特币。
1703865332
1703865333
● 输出。所有输出也排成一个序列。每个输出的内容分成两部分。所有输出的金额之和必须小于或等于输入的金额之和。当输出的总金额小于输入总金额时,输出的总金额与输入的总金额的差额部分,就作为交易费支付给为这笔交易记账的矿工。
1703865334
1703865335
一长串怪怪的(funny)字符看上去像是接收地址。实际上,每个输出都要和一个特定的公钥(地址)对应,所以这一长串字符里面确实有一部分看上去是公钥的哈希值,但里面还有一部分看上去像指令集合的东西,它其实是一个比特币的脚本,下文展开介绍。
1703865336
1703865337
1703865338
1703865339
1703865341
区块链技术驱动金融:数字货币与智能合约技术 3.2 比特币的脚本
1703865342
1703865343
每个交易输出不仅确定了一个公钥,其实同时指定了一个脚本。那脚本是什么?为什么我们要用一个脚本?在这一节我们要学习比特币的工作控制语言,也叫脚本。之后,我们就会懂得为什么要用一个脚本,而不是简单地分配一个公钥。
1703865344
1703865345
最常见的比特币交易,就是通过某人的签名去取得他在前一笔交易中获得的资金。这种情况下,我们希望交易的输出包含这样的信息:“凭借地址X的所有者的签名,才可以获得这笔资金。”我们知道地址其实就是一个公钥的哈希值,所以仅仅说地址X并没有告诉我们公钥在哪里,也没有给我们一个检查签名的方法。所以,交易输出必须这样描述:“凭借哈希值为X的公钥,以及这个公钥所有者的签名,才可以获得这笔资金。”这实际上就是最常见的比特币脚本,如图3.4所示。
1703865346
1703865347
1703865348
1703865349
1703865350
图3.4 P2PH脚本范例
1703865351
1703865352
注:一个常见的比特币输出脚本范例。
1703865353
1703865354
那么谁执行这个脚本?这一系列指令是如何完成的呢?秘密在于,交易的输入包括了脚本(而不是签名)。为了确认一笔交易正确地获取了上一笔交易所输出的资金,我们把交易的输入脚本和上一笔交易的输出脚本串联起来,这个串联脚本必须被成功地执行后才可以获取资金。这两个脚本,一个是输出脚本(scriptPubKey),另一个是输入脚本(scriptSig)。输出脚本只是指定了一个公钥(或是公钥哈希值的地址),输入脚本指定了一个对应公钥的签名。图3.5就是两个脚本结合的案例。
1703865355
1703865356
比特币脚本语言
1703865357
1703865358
这个脚本语言是为比特币开发的。在比特币里只叫作“脚本”。它和另一种Forth语言有很多相似的地方,Forth是一种简单的堆栈式编程语言(stack-based programming language),但你并不需要先学习Forth语言才会使用比特币的脚本语言。比特币的脚本语言设计原则就是简明扼要,并内生地支持加密操作。比如,脚本里面有目的性的指令用来计算哈希值和检验签名。
1703865359
[
上一页 ]
[ :1.70386531e+09 ]
[
下一页 ]