-
Notifications
You must be signed in to change notification settings - Fork 0
/
merkle_tree.py
53 lines (40 loc) · 1.5 KB
/
merkle_tree.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from typing import List
import hashlib
class Node:
def __init__(self, left, right, value):
self.left: Node = left
self.right: Node = right
self.value = value
@staticmethod
def hash(val):
return hashlib.sha256(val.encode('utf-8')).hexdigest()
@staticmethod
def doubleHash(val):
return Node.hash(Node.hash(val))
class MerkleTree:
def __init__(self, values: List[str]):
self.__buildTree(values)
def __buildTree(self, values: List[str]):
leaves: List[Node] = [
Node(None, None, Node.doubleHash(e)) for e in values]
if len(leaves) % 2 == 1:
# duplicate last element if odd number of elements
leaves.append(leaves[-1:][0])
self.root: Node = self.__buildTreeRec(leaves)
def __buildTreeRec(self, nodes: List[Node]):
half: int = len(nodes) // 2
if len(nodes) == 2:
return Node(nodes[0], nodes[1], Node.doubleHash(nodes[0].value + nodes[1].value))
left: Node = self.__buildTreeRec(nodes[:half])
right: Node = self.__buildTreeRec(nodes[half:])
value: str = Node.doubleHash(left.value + right.value)
return Node(left, right, value)
def printTree(self):
self.__printTreeRec(self.root)
def __printTreeRec(self, node):
if node != None:
print(node.value)
self.__printTreeRec(node.left)
self.__printTreeRec(node.right)
def getRootHash(self):
return self.root.value