在上一篇文章中,我们聊了比特币的共识协议——PoW工作量证明机制。我们讲了它如何让比特币网络在众多分布式节点上运行起来,以及蕴含在其中的激励设计在保护比特币网络安全性上是如何的巧妙。
讲完了节点们如何达成共识,我们还需要了解区块链数据是如何存储在节点上的。
由于区块链数据的公开性,如果要求每一个单节点都存储所有的历史交易数据,那么节点们的负担会随着时间的推移而越来越大。而如果因此增加了节点加入网络的成本,使得整个网络中的节点数量变少,那么对整个网络的安全性其实也是有损害的(节点越少,51%攻击的难度也越小)。
因此中本聪使用了默克尔树的特性来减少运行比特币网络给节点带来的存储负担。
默克尔树
默克尔树是区块中数据的组织形式,它的样子是这样的:
可以看到,树的叶子节点(最下边一层)是写进区块的各个交易。
树的其他层,包括根部都是哈希值。树根部的哈希值是通过叶子节点的交易数据一层一层哈希得来的。
图中的交易0和1,各自产生哈希值0和1,然后它俩进行哈希得到哈希值01,接着哈希值01再与同一层相邻的哈希值23一起进行哈希,得到了树根的根哈希。
这个根哈希就是我们之前提到的,存储在区块头中,代表区块中所有交易数据的哈希值。它也是将各个区块链起来的关键。
剪枝
因为哈希的特点,这种层层哈希带来的结果就是,整个区块中任意一笔交易的数据发生变化,即默克尔树任意一个叶子发生了变化,都会导致树的根哈希发生变化。
所以我们可以通过剪除比较老的区块中默克尔树树枝的方式来压缩数据,减少磁盘空间占用,这称为“剪枝”。如下图所示:
简化的支付验证
一个网络节点不需要下载所有的历史交易数据也是可以进行支付验证的。它只需要拥有一个最长工作量证明链的区块头副本即可。
当然,节点必须与其他网络节点进行多次通信,才能知道自己是否拥有了最长的链。
如下图所示,一个节点只存储了最长链的区块头副本。
此时它想要验证一笔交易,名为交易3,是否有效。
交易有效的前提当然是这笔交易已经被网络上的大多数节点所认可,从而被纳入在最长链上了。那么这就意味着节点自己保存的区块头中其实是有交易3所在的默克尔树的树根的。
只是该节点因为只有树根所在的区块头,没有完整的历史交易数据,所以它自己无法验证交易3是否有效。
那么这个轻量节点需要做的就是从网络中获取交易3所在的默克尔树分支,如下图所示:
该节点不需要担心自己拿到的数据是伪造的,因为它可以进行验证。这也是区块链世界中的一条法则:Don’t Trust,Verify。即不需要信任,自己去验证吧。
轻量节点只需要使用获取到的不可信的默克尔树分支来计算根哈希,然后和自己本地可信的区块头中存储的根哈希进行比对,即可知道数据的真实性。如果二者一致,则说明接收到的交易3所在的默克尔树分支是可信的。这笔交易确实已经被纳入到了最长的区块链中,得到了整个网络的信任。
最后
介绍完默克尔树之后,比特币白皮书中的主要内容基本就介绍完了。但为了主题的完整性,收尾还是放到下一篇文章来做。咱们下一篇文章见。



