Hash指针与区块链
Hash指针是对数据存储的位置和数据存储的内容的Hash值的指针。
上面的图是Hash指针指向了一个区块。Hash指针最重要的作用除了能找到区块位置,就是其防篡改性,
Hash指针是如何防篡改的呢?
比如正常的一个区块链就好比底下这张图,这个区块链就三个区块,H3可以是随便的,因为他后面已经没有区块了,H3跟数据3组合后,计算出哈希值,把这个哈希值就赋值给H2,这样H2就指向了区块3。
然后呢,H2跟数据2组合后,计算出哈希值,同样把这个哈希值赋值给H1,这样H1指向了区块2。
接着,H1跟数据1组合后,再计算出哈希值,把这个哈希值赋值给H0,H0就指向了一个区块1。
这样子一个区块链就构造完成了,H0作为这个区块链的入口被公布出去,以后谁想访问这个区块链,只要拿到H0就可以了。(也就是说,H0指针是最后生成的,其过程是一个逆过程。)
如果有人欺诈,想要修改数据3的内容,会发生这样的事情:
- 改了数据3,我们把数据3改成红色。
- 因为老的H2是通过H3跟老的数据3计算出来的,那数据3改了后,为了让H2能再指向区块3,就需要再次计算H2,这样H2就发生变化了,我们把H2改成红色。(注意,由于Hash函数的碰撞阻力,我们可以确定新的Hash值与改变后的内容不会匹配。)
- H2发生变化后,因为老的H1是通过老的H2跟数据2计算出来的,那H2发生变化了,为了让H1能指向区块2,就需要再次计算H1,这样H1就发生变化了,我们把H1改成个红色。
- H1发生变化后,因为老的H0是通过老的H1根数据1计算出来的,那H1发生变化了,为了让H0能指向区块1,就需要再次计算HO,这样H0也发生变化了,我们把H0改成红色。
所以看到因为改了数据3,导致H2,H1,H0都发生了变化。
当这个欺诈者把修改后的这个区块链公布之后,发布这个区块链的入口是新的H0,结果小白用户通过对比发现H0跟原来的不一样,就知道,哦,原来你已经改了这个区块链的内容了。
我们把链表头部的Hash指针称为创世区块,只要保证这个创世区块不能被篡改即可(区块链一书如是说),有人也说实际上创世区块本身并没有做特别的防止篡改措施。在早期的Bitcoin实现中,创世区块也要和普通的区块一样,发给其他结点做一遍校验流程。由于Bitcoin网络中大部分结点倾向于使用合法的客户端实现,因此当其校验无法通过后,该结点本身就无法与其他结点同步。其实没必要校验创世区块。在后来的Bitcoin代码实现中,它本身就是区块链定义的一部分。结点同步1号区块时,里面的父区块hash值需要去创世区块hash值相等。如果创世区块有篡改,hash值就会不同,这样在同步1号区块时就会出错而无法进行下去了。
另外,修改Hash指针的过程:
当父区块有任何改动时,父区块的哈希值也发生变化。这将迫使子区块的“父区块哈希值”字段发生改变,从而又将导致子区块的哈希值发生改变。而子区块的哈希值发生改变又将迫使孙区块的“父区块哈希值”字段发生改变,又因此改变了孙区块哈希值,以此类推。
一旦一个区块有很多代以后,这种瀑布效应将保证该区块不会被改变,除非强制重新计算该区块所有后续的区块。正是这样的重新计算需要耗费巨大的计算量,所以一个长区块链的存在可以让区块链的历史不可改变,这也是比特币安全性的一个关键特征。
综上所述,其不可篡改性可以概括为:
- 重新计算被篡改区块后续区块需要耗费巨量的计算力。
- 存在碰撞阻力。如果创世区块能被篡改,Hash值就会与先前的不同,篡改的Hash值与公布的Hash值不同;如果创世区块不能被篡改,重新计算的Hash值必然也不会匹配原先的Hash值。