深入理解比特币系列(14): 比特币区块链

区块链的数据结构是包含交易信息区块的有序后向链表。Bitcoin Core使用Google的LevelDB数据库存储区块链元数据。区块由后向前有序地链接在一起,每个区块都指向前一个区块,整个链条即构成了比特币区块链。

你可以把比特币区块链想象成地质构造中的地质层或者是冰川岩芯样品。表层可能会随着季节而变化,甚至在沉积之前就被风吹走了。但是越往深处,地质层就变得越稳定。到了几百英尺深的地方,你看到的将是保存了数百万年但依然保持历史原状的岩层。在区块链里,最近的几个区块可能会由于区块链分叉所引发的重新计算而被修改。最新的六个区块就像几英寸深的表土层。但是,超过这六个区块后,区块在区块链中的位置越深,被改变的可能性就越小。在100个区块以后,区块链已经足够稳定,而几千个区块(约一个月)后的区块链将成为历史,永远不会改变。

区块结构

区块是一种被包含在公开账簿(区块链)里的聚合了交易信息的容器数据结构。它由一个包含元数据的区块头和构成区块主体的一长串交易组成。区块头是80字节,平均每个交易至少是250字节,而平均每个区块至少要包含超过500个交易。因此,一个包含所有交易的完整区块要比区块头的1000倍还要大。一个区块具体的数据结构如下所示:

Size Field Description
4 bytes Block Size The size of the block, in bytes, following this field
80 bytes Block Header Several fields form the block header
1–9 bytes (VarInt) Transaction Counter How many transactions follow
Variable Transactions The transactions recorded in this block

区块头

区块头除去软件版本信息外,有5个重要的元数据组成:父区块哈希值、难度、时间戳、随机数nonce及merkle树根。

父区块哈希用于该区块与区块链中前一区块相连,难度、时间戳及随机数nonce与区块的产生相关、merkle树根是一种用来有效地总结区块中所有交易的数据结构。具体区块头数据结构如下:

Size Field Description
4 bytes Version A version number to track software/protocol upgrades
32 bytes Previous Block Hash A reference to the hash of the previous (parent) block in the chain
32 bytes Merkle Root A hash of the root of the merkle tree of this block’s transactions
4 bytes Timestamp The approximate creation time of this block (seconds from Unix Epoch)
4 bytes Difficulty Target The Proof-of-Work algorithm difficulty target for this block
4 bytes Nonce A counter used for the Proof-of-Work algorithm

区块哈希

区块哈希更准确的名称应该是:区块头哈希,因为它是通过SHA256算法对区块头进行两次哈希计算而得,即只有区块头被用于计算。区块哈希可以唯一、明确地标识一个区块,并且任何节点通过简单地对区块头进行哈希计算都可以独立地获取该区块哈希。

区块高度

区块高度的含义是区块在区块链中的位置。创世区块的高度是0。与区块哈希不同的是,区块高度并不能唯一的标识区块,即可能有两个或两个以上的区块有相同的区块高度。

创世区块

比特币区块链的第一个区块创建于2009年,被称为创世区块。它是比特币区块链里所有区块的共同祖先,这意味着你从任一区块,循链向后回溯,最终都将到达创世区块。

因为创世区块被编入到比特币客户端软件里,所以每个节点都始于至少包含一个区块的区块链,这能确保创世区块不会被改变。每个节点都“知道”创世区块的哈希、结构、被创建的时间和里面的一个交易。因此,每个节点都把该区块作为区块链的首区块,从而构建了一个安全的、可信的区块链的根。

创世区块哈希如下:

000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

从Bitcoin Core参考实现命令行我们可以得到更详细的创世区块信息:

$ bitcoin-cli getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
{
    "hash" : "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
    "confirmations" : 308321,
    "size" : 285,
    "height" : 0,
    "version" : 1,
    "merkleroot" : "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
    "tx" : [
        "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
    ],
    "time" : 1231006505,
    "nonce" : 2083236893,
    "bits" : "1d00ffff",
    "difficulty" : 1.00000000,
    "nextblockhash" : "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
}