Hash pointer
指针
在程序运行过程中,需要用到数据。最简单的是直接获取数据,但当数据本身比较大,需要占用较大空间时,明显会造成一定麻烦。因此,可以引入指针这一概念。当需要获取数据时,只需要按照指针所给的地址,去对应的位置读取数据即可,这样大大节省了内存空间。在实际中,为了便于程序移植性等原因,指针实际存储的是逻辑地址而非物理地址。
哈希指针
如下图,我们可以看到有两个指针指向这个节点,其中P为该节点的地址,H()为该节点的哈希值,该值与节点中的内容相关。当节点中的内容发生改变,从而保证了这个节点的内容不能被篡改。
区块链
区块链中使用哈希指针代替了普通指针,每个区块根据自己的区块内容生成自己的哈希值,此外,每个区块都保存有前一个区块的哈希值,从而保证了区块内容不会被篡改。
在实际应用中,一整条链可能分开保存在多个地方。若用户仅仅具有其中一段,当用到前面部分区块数据时,直接问系统中其他节点要即可,当要到时,仅仅通过计算要到的最后一个哈希值和自己保存的哈希值是否一致,就可以判断所给的内容是否确实为区块链上真实的内容。
这样的数据结构就一个明显的特点是,改变任意一个区块的内容,都会触发多米诺骨牌效应,需要区改变每一个区块的内容。其次,这种数据结构下,计算节点不用去保存所有完整的区块,如果需要某个不存在于自身的区块,可以去向其他的节点请求区块信息,同时可以通过计算哈希值来验证其真实性,因为每个节点都保存了上一个节点的哈希值。
Markle Tree
markle tree又是比特币系统中又一个重要的数据结构,markle tree和binary tree很类似,但核心区别还是使用了哈希指针。
上图即为一个简单的Markle Tree,其中ABCD为数据块。A和B各有一个哈希值,将其合并放在一个节点中,C和D同理。而后针对两个节点分别取哈希,又可以得到两个新的哈希值,即图中的根节点,再对根节点取一次哈希,就可以得到整个Markle Tree的root hash。
该数据结构的优点在于,只需要记住root hash,便可以检测出对树中任何部位的修改。例如,上图中B节点发生了改变,对应第二层中第一个节点中第二个哈希值也会发生改变,进而根节点中第一个哈希值也会发生改变,从而导致root hash也会发生改变。
Markle Tree的实际用途
在比特币系统中,不同的区块通过hash pointer链接。在同一个区块中的多个交易(数据块),通过Markle Tree的形式组织在一起。区块本身分为两部分(block hearer和block body),在block header中存在有root hash(没有交易的具体信息),block body中存放交易列表。
Markle Tree可以用于提供Markle Proof。关于Markle Proof,需要先了解比特币系统中节点。比特币中的节点分为轻节点和全节点,全节点保存整个区块所有内容,而轻节点仅仅保存区块的块头信息。
当需要向轻节点证明某条交易是否被写入区块链,便需要用到Markle Proof。我们将交易到根节点这一条路径称为Markle Proof,全节点将整个Markle Proof发送给轻节点,情节点既可以根据其算出root hash,和自己保存的对比,从而验证该交易是否被写入到区块链中。只要沿着该路径,所有哈希值都正确,说明内容没有被修改过。
这样一个Markle Proof的时间复杂度为O(log n),非常高效【证明交易存在】。如果要证明交易不存在,如果不对叶子节点规定排序,没有一个高效证明不存在,在比特币系统中,也没有这样的需求,所以在比特币系统中没有对Markle Tree进行排序。
思考
是否存在不安全的情况?如下图我们要验证B,但是H(1)和H(4)都是全节点提供的。全节可否修改B的交易数据,然后通过调整H(1)的值,使得修改过后H(1)和轻节点计算出的H(2)一起取得哈希仍然为H(3)?
实际上,这种情况属于人为制造哈希碰撞。由于加密散列函数的collision resistance性质,这种情况是不会发生的。从而保证了系统的不可纂改。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。