比特币的脚本系统 | 区块链技术普及9.7

从区块到交易,再从交易到输入输出,我们越来越深入比特币的“内脏”了,今天再往前走一步,看看比特币的脚本系统是个什么样子。

比特币的脚本系统是智能合约的一个雏形,但它不是图灵完备的,因为它没有跳转语句和循环语句,这两种语句特别容易引发安全漏洞,而比特币的设计是把安全放到第一位的,所以做出了这样的妥协。 比特币的脚本系统是后进先出的堆栈模型。

什么叫堆栈?

你可以想象一个箱子,你往箱子里一层层地堆木板,堆完后要拿出来时,只能先拿最顶上的那块,也就是最后堆上去的那块,再拿倒数第二块,依次类推,后进先出。

比特币的锁定脚本和解锁脚本,就是将数据一层一层压入堆栈,然后再从上往下进行处理的过程。 我们从区块浏览器上找一笔交易来对照进行学习。
这里写图片描述

这笔交易里有1个输入(注意:输入右边括号里的“输出”,是指你点进去,可以看到是哪笔交易输出给这个输入的),两个输出,大家看看能不能找到对应的交易字段?

不过,今天我们的重点不在这里,重点在下面这个图,这笔交易的解锁脚本和锁定脚本:

这笔交易只有1个输入,所以只有1个输入脚本,也就是锁定脚本;有2个输出,所以有2个输出脚本,也就是锁定脚本。

锁定脚本和解锁脚本是成对使用的,成对并不是指上图那样同一笔交易里的输入和输出,而是指这笔交易的输入和上笔交易的输出,或者这笔交易的输出和下笔交易的输入。

因为这笔交易输出的比特币是“未使用”状态(见上图),还没有下一笔交易。所以,我们只能拿这笔交易的输入和上笔交易的输出来学习了,点击上图的“输出”可以找到对应的输出。我们把这对输入输出的锁定脚本和解锁脚本提取到一起。
这里写图片描述
锁定脚本:
这里写图片描述

解锁脚本:

这里写图片描述
别看这些指令好像高深莫测,但我们前面已经积累了大量基础知识,所以学习起来并不难,学完后你会发现这些指令实现的功能其实很简单。

执行时,先执行解锁脚本的指令,再执行锁定脚本的指令。

ScriptSig就是解锁脚本的意思,因为在原始交易代码中,就是“ScriptSig”这个字段来表示签名部分,签名部分包含签名和公钥。所以,这只是一个说明而已,不用管;

PUSHDATA(71)的意思是将后面的71个字节压入堆栈(堆栈就是一个箱子);

[]里的这72个字节就是签名,所以,先把签名压到栈底了;

PUSHDATA(33)就是将后面的33个字节压入堆栈,[]里的33个字节是一个公钥。

解锁脚本执行完毕,堆栈里有了一个签名和一个公钥,签名在栈底,公钥在栈顶。 继续执行锁定脚本的代码。

DUP的意思是把栈顶的数据复制一份,这样,堆栈里就有了3个数据,从底往上是:签名+公钥+公钥;

HASH160是对栈顶数据进行哈希运算,于是得到一个公钥Hash,堆栈从底往上变成:签名+公钥+公钥哈希;

PUSHDATA(20)将后面[]里的20个字节放到栈顶,这20个字节也是公钥哈希,堆栈从底往上变成:签名+公钥+公钥哈希+公钥哈希;

EQUALVERIFY是比较栈顶的两个数据是否相等并弹出,如果不等,说明本次交易的发送地址并不是上笔交易指定的目的地址,执行失败;如果相等,脚本会继续执行,堆栈只剩:签名+公钥;

CHECKSIG的功能就是利用公钥对签名进行验证,本来是一件挺复杂的事,但一条指令搞定。验证通过后,交易才是有效的。

是不是很简单?还是一脸懵逼?没关系,多看几次,再结合前面的文章,就懂了。网上有完整的比特币指令大全,有兴趣的童鞋可以去看看。

阅读更多 登录后自动展开

更多精彩内容