理论知识
MerkleTree,中文名默克尔树,更加通俗的讲就是哈希二叉树!
这种树在1980年就已经被merkle ralf这个人提出了,曾经广泛文件系统和 P2P 系统中。
那么接下去就简明扼要的讲一下它的特点:
直接上图:
由图可知其特点:
1.其叶子节点包含存储数据以及其对应的哈希值
2.其他的节点(包括根节点)都是其儿子节点内容的哈希值
3.由以上两点可知:只要底层数据篡改,上层的哈希值必将变动,那么即可迅速定位某个被篡改的节点。
4.可以不通过给定所有节点完整数据,只需要给兄弟节点的哈希值,即可证明该节点是否为正常无篡改节点。
实现代码
本人近期在制作区块链的时候,自己写了一个merkle tree代码如下,如有错误请纠正,谢谢!(采用go语言的)
func (block *Block) HashTransactions() []byte {
//参数block是区块链中的区块,返回的是merkle root的字节
var txHashes [][]byte
//数组txhashes是每个交易tx的hash值
var txHash [32]byte
var flag = len(block.Txs) - 1
//取出交易tx的hash放入数组txhashes
for _, tx := range block.Txs {
txHashes = append(txHashes, tx.TxHash)
}
//若长度为1,也就是最后一个下标为0
//则让它对该交易取一次hash即可
if flag == 0 {
txHash = sha256.Sum256(txHashes[0])
txHashes[0] = txHash[:]
}
//若不是
//则每两个节点组成一个hash节点,向上传递,递归下去
for flag != -1 && flag != 0 {
j := 0
for i := 0; i < flag; i += 2 {
//若奇数个交易则最后一个单独取hash
if i < flag {
txHash = sha256.Sum256(bytes.Join([][]byte{
txHashes[i], txHashes[i+1]}, []byte{
}))
//若偶数个交易则刚好两两配对(两两hash相连再取hash)
} else {
txHash = sha256.Sum256(bytes.Join([][]byte{
txHashes[i]}, []byte{
}))
}
//将结果存回原先的数组,也就是覆盖原先的数组
txHashes[j] = txHash[:]
fmt.Println(txHashes[j])
//并且修改数组的长度
j++
}
//取最后一个下标
flag = j - 1
}
fmt.Println(txHashes[0])
//最后返回第一个hash,也就是根hash
return txHashes[0]
}