代码位置:bitcoin/src/primitives/block.h
每个区块通过 hashPrevBlock 连接,从创世块开始组成一个链。这也就是区块链名字的由来。每个区块存储当前一段时间内的交易记录,也就是 vtx。
这样一条链可以防止双花,可以防止篡改以前的交易记录。所以为什么可以?看到最后你就懂了。
任何一个比特币网络的完整节点都独立保存了一条链。这条链上的每个区块都经过该节点验证。当有多个节点拥有这样相同的一条链时,我们就说这些节点达成了共识。这些节点所遵循的共同的验证规则我们称为共识规则。好吧,你叫共识算法也行。
直接上简化的比特币区块链示意图。
通过这个图大家可以理解一下链的意思。这个 MerkleRoot 咋来的呢?莫急,后面讲到交易的时候会涉及到。就是 Merkle 树的根。Merkle 树是一种哈希树。对一个区块里面的所有交易两两哈希。然后再两两哈希,直到最后得到一个哈希值,这个哈希值就是 Merkle 根。有点懵?没关系,后面会讲清楚。
大家可以看到,Merkle 根和上一个块头的哈希值都存在当前区块头里。这样就把所有区块连在一起,形成区块链。如果你想修改其中的一个交易记录,必须修改当前区块的信息和后续所有区块的信息。你会说,那就一起修改呗。不好意思,其他节点可不答应。后面慢慢体会。
不但区块是一条链,交易记录都是连在一起的。请看下图。
一个交易记录可以产生多个输出。但是每个交易输出只能做一次交易的输入。这就避免了双花问题。
输出是和交易ID关联的。这个交易ID是签过名交易记录经过哈希得来的。区块链里的所有输出只包含两种,未花费输出(UTXOs)和已花费输出。输入是不是未花费输出,可以用来判断支付是不是有效。
除了 coinbase 交易(不知道怎么翻译coinbase),如果交易输出的值大于输入的值,交易会被大家拒绝。很好理解,你有五块,要花十块钱,你觉得可以吗?相反的,如果交易的输入值大于输出值,不好意思,这个差值会当做交易费支付给当前出块且包含了本次交易的矿工。就是俗称挖到矿的幸运儿。这笔交易费包含在 coinbase 交易里面。所谓 coinbase 交易就是每个区块的第一笔交易。就是奖励给矿工同志的。天天挖矿很累的!上图中的例子你会发现每笔交易,输出都比输入少了 10000 聪。这就是交易费。好吧,你也可以叫手续费。
说了这么一通,还是上点代码吧。
代码位置:bitcoin/src/primitives/transaction.h
大家看到代码里vin是交易的输入,vout是交易的输出。computHash() 这个函数就是计算那个交易ID了吧。还有个 nLockTime 是啥?应该是这个钱还可以锁定时间吧。没关系,后面会详细解析代码的。先混个脸熟。