Preliminary understanding and code implementation of MerkleTree in blockchain

theoretical knowledge

MerkleTree, the Chinese name is Merkle tree, more popularly speaking, it is a hash binary tree!
This kind of tree was proposed by Merkle Ralf in 1980 and was once widely used in file systems and P2P systems.
Then let’s briefly talk about its characteristics:
Directly above the picture:
spaces_-M5xTVjj6plOWgHcmTHq_uploads_git-blob-01dd48b2fe29d3d5ba879d8eddfe6db037b13596_Merkle_tree.webp
From the picture we can see its characteristics:
1. Its leaf nodes contain stored data and its corresponding hash value
2. Other nodes (including the root node) are the contents of its child nodes Hash value
3. From the above two points, we can know that as long as the underlying data is tampered with, the hash value of the upper layer will definitely change, so a tampered node can be quickly located.
4. Instead of giving the complete data of all nodes, you only need to give the hash value of the sibling node to prove whether the node is a normal node without tampering.

Implement code

When I was making a blockchain recently, I wrote a merkle tree code as follows. If there are any errors, please correct them. Thank you! (using go language)

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]
}

Guess you like

Origin blog.csdn.net/qq_46255801/article/details/131731276