前面一篇学习笔记01提到了一个交易模型(第三章的内容),在第五章中,除了对这个模型做个详细介绍之外,其实和我上一篇理解的交易模型差不多,一个交易包含输入与输出,比特币是在各个地址之间转移,不想中心化系统例如银行有个服务器,记录了每个人的账户,账户这个结构体包含:交易记录,账户余额等一切信息,但是在比特币交易网络这种去中心化的体系中,比特币的交易记录,一个账户拥有多少比特币等信息存储在了区块链中,要像银行账户一样,查询自己账户的相关信息,只能通过查区块链中的区块获取,就像从数据库里查询数据一样,就像下面比特币的交易模型描述。
模型图有几个重点:
个人可用的比特币是以账单形式存在的,在发起交易时,查询区块链中个人可用账单(账单输出账户是你),使用账单来支付相应比特币,产生输出,实际上,是比特币在比特币地址之间的转移。
本次交易的输入就是上次交易输出,比特币账户(地址)查询余额和交易,就是对区块链里账单里对你账户输出的查询(上图中,对A可支配比特币的查询账单输出:退给A的金额,对B可支配比特币的查询账单输出:转账给B的金额)
本次交易的输入可以只有一张账单的输出(如果这张账单上的比特币足够),也可以包含几张账单的输出(几张账单加起来比特币>=此次需要支付金额),注意到,上面的>=比交付,因为不太可能利用已有账单完全无误差地凑出本次需支付对应金额,因为账单里的输出金额是不可拆分的,只能利用账单来支付,要将银行里控制的个人账户余额(一串数字)与比特币个人账户余额(账户下的账单输出)区分开来。
生成的账单三中有给矿工的奖励,这个奖励是你自定的,给不给,给多少都行,这个奖励影响的是交易的优先级,奖励越多,越能尽早地将账单加入区块链中,以保证交易的完成。账单将会被保存在矿工的矿池中,按照奖励优先级来处理账单。
交易输出的锁定与解锁(重点)——锁定脚本与解锁脚本上面提到了,一个账户可支配的比特币来源于账单的输出,而账单是公开的,每个比特币账户都能知道这笔交易以及交易的输出,那么怎么保证输出只有对应的比特币的账户能用呢?
比特币的锁机制是通过一种类Forth语言脚本来,该脚本语言是种非图灵完备的语言,什么是图灵完备的语言呢,当一门编程语言在不限制内存和不限制时间下,能够解决所有问题,就称为图灵完备的,例如:C/C++,JAVA都是图灵完备语言,反之就是图灵非完备,比特币脚本里没有循环,所以这个脚本不能解决:在满足某种条件下退出循环,否则无限制地循环的问题。比特币的脚本语言是一种简单、低级的语言,它的很多功能已经被编译成立二进制文件,即使我们不了解这种语言,只要能够调用接口就行了,或者可以直接使用C/C++,JAVA这样的语言来完成锁定和解锁的功能。那么为什么不直接用C++等图灵完备的语言呢?这是出于安全考虑的,因为C++,JAVA等语言与内存、操作系统等运行环境,息息相关,而比特币脚本不需要任何运行环境都能运行,这就能抵抗基于内存的攻击或者其他透过系统漏洞的攻击(书上是这样解释的,我觉得,比特币脚本更像一串机器语言的0-1串,由于低级机器语言的限制,很难进行高级编程,同样的,也保证了安全性,因为0-1机器语言很难入侵更改)。
下面是锁定脚本与解锁脚本的例子,以说明锁的交互机制。
假设这笔交易为A向B支付比特币,在交易双方完成交易,生成账单时(非矿工加的解锁和锁定脚本),A向这个账单加上了锁定脚本,这个锁定脚本包含B的比特币地址C,因为B只公开了经过对公钥HASH后的比特币地址C,因为HASH函数的性质,比特币网络上的任何人,都不能通过C逆向得到B的公钥,也就是说,只有B知道自己的公钥能够构建解锁脚本,即只有B的公钥,才能通过HASH运算出地址C,只有能运算出地址C的比特币账户,才能支配这笔比特币。
脚本语言运行