每天在比特币这个区块链网络中都会发生大量的交易,每笔交易都需要经过半数以上的节点确认,才会最终将这笔交易信息写入块中。那么,对于像交易业务这么重要的数据,比特币网络又是如何处理的呢?
要回答这个问题,就需要知道比特币的两种数据结构——区块链和Merkle Tree.
区块链
什么是区块链?
区块链就是由一个个的区块组成地链表。
和普通链表使用只保存结构体内存地址的指针相比,区块链使用的是既可以保存结构体内存地址又可以保存结构体信息哈希值的指针,它称为哈希指针。
我们简单用张图给大家展示一下区块链结构:
这种结构由于使用了哈希指针,那么我们就可以只保存最近几个区块或者最后样一个区块的哈希就能监控整个区块链表。比如,当h(0)这个区块的内容发生了变化,那么h(1)就会发生变化,因为h(1)这个哈希值就是根据h(0)以及h(0)所在的区块内容计算出来的;相应的h(2)、h(3)的值都会发生变化,最终导致计算出来的哈希值发生了改变。这时候,我们就会发现这个计算出来的哈希值和我们之前保存和哈希值不一致了;这也意味着说,前面的区块一定被篡改了。而且,我们还可以通过反向验证的方式找到是前面的哪个区块发生了篡改。基于这样的结构关系,比特币的区块链实现了tamper-evident log(篡改记录日志)。
简单来说,普通链表中部分指针发生变化并不会对链表其他部分产生影响,而比特币使用的区块链表则具有多米诺骨牌效应,任何一个部分发生变化,都会导致其后所有区块发生变化。
Merkle Tree
什么是Merkle Tree?我们同样需要用图来给大家说明一下。
从图中,我们可以看到Merkle Tree最底下那一层称之为data blocks(数据块),上面则都是带有hash pointers(哈希指针)的区块。具有计算机基础的同学应该都知道,这是一种二叉树结构。不过,这种二叉树比特别,因为树干部分都是带有哈希指针的。而且,哈希值h(0)是根据底层从左往右第一个数据块的内容计算出来的,以此类推,底层8个数据块就计算出了上一层8个哈希值。从上往下看,h(8)是由h(0)、h(1)以及它们所在区块保存的内容共同计算出来的,h(9)又是由h(0)、h(1)以及它们所在区块保存的内容共同计算出来的…最终就可以计算出一个root hash(根哈希值),保存在本地。根据我们对于区块链表的理解,根哈希值同样也能够检测Merkle Tree所有部分的篡改行为。
我们还需要了解的是,每个区块分成两个部分——block header(块头)& block bady(块身)。其中,root hash就保存在block header中,而区块的交易信息就保存在block bady中。
Merkle Tree的校验又是如何完成的呢?
实际上,比特币中的节点分为轻节点和全节点。轻节点只是记录block header中的root hash的节点,比如,我们安装在智能手机中的比特币钱包就属于轻节点应用,而全节点是包含这个区块中发生的所有交易信息的。
那么,在校验过程中,又涉及了一个叫做Merkle Proof的部分。上图中的tx就代表着交易信息,它是保存在底层的区块中的,它与h(1)、h(9)、h(13)等用绿色标示的哈希指针共同构成了一个Merkle Proof。当轻节点收到这笔交易的Merkle Proof之后,就可以通过tx计算出h(0),计算出h(0)之后,又可以通过h(0)、h(1)计算出h(8)…以此类推,最终也可以计算出一个root hash。这时,就可以拿着这个计算出来的root hash和之前保存在本地的root hash比较一下,如果一致,说明这笔交易实际发生没有经过篡改并且已经写在被校验的区块中了。
如果还不是很好理解的话,我们还可以简单地粗略地这么来看。我们就把整个Merkle Tree当作block bady,他负责保存具体的交易列表,而轻节点就可以当成block header,它只负责保存root hash,用于监督Merkle Tree。
总结
比特币通过区块链表和Merkle Tree存储交易数据
区块链和Merkle Tree都带有哈希指针,这使得并不是所有节点都需要保存所有区块,而只要保存最近区块的root hash即可
Merkle Proof可以证明Merkle Tree里面包含了某笔交易,这种证明称之为Proof of Membership