diff --git a/merkleTree.py b/merkleTree.py index 373717b..ea4cb68 100644 --- a/merkleTree.py +++ b/merkleTree.py @@ -12,15 +12,15 @@ def __init__(self, data): self.data = data self.left = None self.right = None - + #utility function to check if a given node has 2 children def isFull(self): return self.left and self.right - + #utility function to print the contents of the node def __str__(self): return self.data - + #utility function to check if a given node has 0 children (is a leaf node) def isLeaf(self): return ((self.left == None) and (self.right == None)) @@ -32,100 +32,100 @@ class merkleTree: def __init__(self): self.root = None self._merkleRoot = '' - - # private utility function to return a hash of an input string, using the sha256 algorithm + + # private utility function to return a hash of an input string, using the sha256 algorithm def __returnHash(self, x): return (hashlib.sha256(x.encode()).hexdigest()) - + # function to generate a tree from a list. The list is expected to contain - # the list of transactions(as strings) we wish to seal in a block + # the list of transactions(as strings) we wish to seal in a block def makeTreeFromArray(self, arr): - + # all the elements of the list must be leaf nodes, hence total nodes in the tree # is [2*(noOfLeafNodes) - 2] def __noOfNodesReqd(arr): x = len(arr) return (2*x - 1) - + # Private function to build tree with a list generated by a sequence corresponding to the # number of nodes required for the tree. # For e.g. if we have 4 transactions, i.e. 4 leafNodes, we will have a total of 7 nodes - # in the tree. Hence this function takes in a list that looks like [1,2,3,4,5,6,7] and + # in the tree. Hence this function takes in a list that looks like [1,2,3,4,5,6,7] and # creates a binary tree by recursively inserting elements in inorder fasion. - def __buildTree(arr, root, i, n): - - # Base case for recursion - if i < n: - temp = Node(str(arr[i])) - root = temp - - # insert left child - root.left = __buildTree(arr, root.left,2 * i + 1, n) - - # insert right child - root.right = __buildTree(arr, root.right,2 * i + 2, n) - + def __buildTree(arr, root, i, n): + + # Base case for recursion + if i < n: + temp = Node(str(arr[i])) + root = temp + + # insert left child + root.left = __buildTree(arr, root.left,2 * i + 1, n) + + # insert right child + root.right = __buildTree(arr, root.right,2 * i + 2, n) + return root - + # This function adds our transactions (leaf Node data) to the Leaf Nodes in the tree # hence now the tree looks like : # "" # /\ # "" "" # /\ /\ - # (txn1) (txn2) (txn3) (txn4) + # (txn1) (txn2) (txn3) (txn4) def __addLeafData(arr, node): - + if not node: return - + __addLeafData(arr, node.left) if node.isLeaf(): node.data = self.__returnHash(arr.pop()) else: node.data = '' __addLeafData(arr, node.right) - + # Driver function calls of the main function makeTreeFromArray nodesReqd = __noOfNodesReqd(arr) nodeArr = [num for num in range(1,nodesReqd+1)] - self.root = __buildTree(nodeArr) + self.root = __buildTree(nodeArr, self.root, 0, nodesReqd) __addLeafData(arr,self.root) - # utility function to traverse the tree using inorder Traversal algorithm + # utility function to traverse the tree using inorder Traversal algorithm def inorderTraversal(self, node): if not node: return - + self.inorderTraversal(node.left) print(node) self.inorderTraversal(node.right) - + # function to calculate merkle root of the tree. This is a recursive algorithm. - # Essentially, the data of parent node P, is the hash of concatenation of data of its two + # Essentially, the data of parent node P, is the hash of concatenation of data of its two # child nodes, A and B. If H(x) is the hash function, # P = H( H(A) + H(B) ) - # If R is the root, then data of R is the merkle hash or merkle root. + # If R is the root, then data of R is the merkle hash or merkle root. def calculateMerkleRoot(self): - + def __merkleHash(node): if node.isLeaf(): return node - + left = __merkleHash(node.left).data right = __merkleHash(node.right).data node.data = self.__returnHash(left+right) return node - + merkleRoot = __merkleHash(self.root) self._merkleRoot = merkleRoot.data - - return self._merkleRoot + + return self._merkleRoot #utility function to get the merkle Root of that tree def getMerkleRoot(self): return self._merkleRoot - + # utility function to verify if the transactions are intact with respect to this tree. # say we know transaction list A is intact and original. We create a merkle Tree with that. # Now we want to know whether the original list of transactions has been tampered with, @@ -144,4 +144,4 @@ def verifyUtil(self, arr1): else: print("Transactions have been tampered") return False - +