Merkle tree based on Python implementation

       The common structure of a Merkle tree is a binary tree, but it can also be a multi-fork tree, which has all the characteristics of a tree structure. The basic data of the Merkle tree is not fixed, and you can store any data you want, because it only needs the hash value obtained by hashing the data. The Merkle tree is calculated layer by layer from bottom to top, each intermediate node is calculated based on the combination of two adjacent leaf nodes, and the root node is calculated based on the combination of two intermediate nodes, so the leaf node is the basis. Therefore, any changes to the underlying data will be propagated to its parent nodes, all the way to the root node of the tree.

      The Merkle tree is one of the important security means used in blockchain technology to protect data from tampering, and it plays a very important role. The following example demonstrates the construction of a Merkle tree by traversal, and calculates and displays the hash value of each step.

import hashlib #for hash value calculation
#Definition of the Merkle tree node class
class MerkleNode(object):
    def __init__(self,left=None,right=None,data=None):
        self.left = left
        self.right = right
        # The hash value is stored in data
        self.data = data

#Build Merkle tree recursively
def createTree(nodes):
    list_len = len(nodes)
    if list_len == 0:
        return 0
    else:
        while list_len %2 != 0:
            nodes.extend(nodes[-1:])
            list_len = len(nodes)
        secondary = []
        #Merge nodes in pairs and calculate their hash value
        for k in [nodes[x:x+2] for x in range(0,list_len,2)]:
            d1 = k[0].data.encode()
            d2 = k[1].data.encode()
            md5 = hashlib.md5()
            md5.update(d1+d2)
            newdata = md5.hexdigest()           
            node = MerkleNode(left=k[0],right=k[1],data=newdata)
            secondary.append(node)
        if len(secondary) == 1:
            return secondary[0]
        else:
            return createTree(secondary)
        
#Use the breadth-first search algorithm to traverse the node data
def BFS(root):
    print('Start breadth-first search, build Merkle tree...')
    i=0
    queue = []
    queue.append(root)
    while(len(queue)>0):
        e = queue.pop(0)
        i+=1
        #print("Hash Value:"+str(i),e.data)
        if e.left != None:
            queue.append(e.left)
        if e.right != None:
            queue.append(e.right)
        print("Hash value:"+str(i),e.data)


if __name__ == "__main__":
    blocks = ['node1','node2','node3','node4'] #Sample data, including 4 nodes
    nodes = [] #node initialization
    print("node hash:")
    for element in blocks: #Traverse sample data
        md5 = hashlib.md5() #Digest algorithm
        md5.update(element.encode())
        d=md5.hexdigest() #Compute the information summary of the node
        nodes.append(MerkleNode(data=d)) #Add to the Merkle tree node
        print(element+":",d)
    root = createTree(nodes) #Create Merkle root node
    BFS(root) #Construct Merkle tree based on BFS algorithm and output all hashes (summary)

The running screenshot is as follows:

 

Guess you like

Origin blog.csdn.net/qq_31391601/article/details/127271302