区块链的数据结构
区块链结构本身为一条链表,节点为区块。而传统链表实现,便是通过指针将各个节点串联起来而称为最终的链。
但在区块链系统中,并未采用指针,而是使用了**哈希指针**。
指针
指针是一种变量,它存储的是另一个变量的内存地址。通过指针,程序可以间接访问或操作存储在该地址中的数据。
哈希指针
哈希指针是一个包含两个部分的数据结构
- 指针:指向特定数据的位置(如内存地址或磁盘位置)。
- 哈希值:该位置数据通过哈希函数计算得出的哈希值。用 H()表示
其中 P 为该节点的地址,H()为该节点的哈希值,该值与节点中内容有关。当节点(区块)中内容发生改变,该哈希值也会发生改变,从而保证了区块内容不能被篡改。
在区块链中的应用:
每个区块通过哈希指针链接到前一个区块,形成一条不可篡改的链。 如果要改其中某一个节点,则意味着后续所有节点都将发生改变。因此,而用户只需要记住最后一个区块链的哈希地址,就可以检测区块链上内容是否被篡改。
默克尔树(Merkle tree)
Merkle Tree 是比特币系统中又一个重要的数据结构,用于快速验证区块中交易的完整性。
上图即为一个简单的 Merkle Tree,其中 A、B、C、D 为数据块。
A 和 B 各有一个哈希值,将其合并放在一个节点中,C 和 D 同样操作,而后,针对得到的两个节点分别取哈希,又可以得到两个新的哈希值,即为图中根节点。实际中,在区块块头中存储的是根节点的哈希值(对其再取一次哈希)。
交易A, 交易B, 交易C, 交易D
哈希A, 哈希B, 哈希C, 哈希D
父节点:
哈希AB = Hash(哈希A + 哈希B)
哈希CD = Hash(哈希C + 哈希D)
根节点:
默克尔根 = Hash(哈希AB + 哈希CD)
课程图示例:
- data blocks: 即为交易 transaction 。
- 在比特币系统中,不同区块通过哈希值指针连接,在同一个区块中的多个交易(数据块),则通过 Merkle Tree 的形式组织在一起。
- 区块本身分为两部分(块头和块身),在块头中存在有根哈希值(没有交易的具体信息),块身中存在交易列表。
该数据结构的优点在于:只需要记住 Root Hash
(根哈希值),便可以检测出对树中任何部位的修改。 例如,所绘制 Merkle Tree 中节点 B 发生了改变,则对应的第二层第一个节点中第二个哈希值便也会发生改变,进而根节点中第一个哈希值也会发生改变,从而导致根哈希值也发生了改变。
在区块链中的应用:
Merkle Tree
可以用于提供 Merkle Proof
( 默克尔证明,用于验证某个交易是否包含在 merkle tree)。
比特币中节点分为轻节点和全节点。全节点保存整个区块的所有内容,而轻节点仅仅保存区块的块头信息。 比特币节点分为:
- 全节点 (block header + block body): full node / full validating node
- 轻节点 (block header): light node
为什么要分轻节点和全节点?
因为硬件的局限。一个区块大小为 1MB,对于移动便携设备来说,如果存储区块的所有内容,则所需空间过大,而这是不现实的。所以轻节点只需要存储区块块头信息,全节点存储区块所有内容即可。
当需要向轻节点证明某条交易是否被写入区块链,便需要用到 Merkle proof。
我们将交易到根节点这一条路径称为 Merkle proof,全节点将整个 Merkle proof 发送给轻节点(如下图所示),轻节点即可根据其算出根哈希值,和自己保存的对比,从而验证该交易是否被写入区块链。只要沿着该路径,所有哈希值都正确,说明内容没有被修改过。