Beispiel #1
0
 def __init__(self, left, right, hash: str = None):
     self.left = left
     self.right = right
     if hash is None and left is not None and right is not None:
         self.hash = Hasher.hash(left.hash + right.hash)
     else:
         self.hash = hash
Beispiel #2
0
    def construct(self, items: list, size):
        if size is None:
            size = len(items)
        layer = [MerkleNode(None, None, Hasher.object_hash(items[x])) for x in range(size)]
        self.number_of_nodes += len(layer)
        self.number_of_hashs += len(layer)

        while len(layer) > 1:
            if len(layer) & 1 == 1:  # add an extra null node
                layer.append(MerkleNode(None, None, ""))
                self.number_of_nodes += 1

            up_layer = []
            for i in range(0, len(layer) - 1, 2):
                up_layer.append(MerkleNode(layer[i], layer[i + 1]))
            self.number_of_nodes += int(len(layer) / 2)
            self.number_of_hashs += int(len(layer) / 2)
            layer = up_layer

        # return the root
        if len(layer) == 1:
            return layer[0]
        else:
            self.number_of_nodes += 1
            return MerkleNode(None, None, "")
Beispiel #3
0
    def verify_chain(block_headers: list, transactions: list):
        """
        Verify if a given chain is valid.
        :param block_headers: list of block headers
        :param transactions: list of transactions of each block
        :return: True if the given chain is valid
        """
        if len(block_headers) != len(transactions) and len(block_headers) == 0:
            return False

        # an valid chain contains only the genesis block
        if len(block_headers) == 1:
            return True

        # validate the all the rest of blocks
        for i in range(len(block_headers)):
            # check if the block links to the previous block except the genesis block
            if i > 0:
                if block_headers[i].previous_hash != Hasher.object_hash(block_headers[i-1]):
                    return False

            # create transaction merkle tree and get the root
            if block_headers[i].transaction_root != ZeroMerkleTree(transactions[i]).root_hash:
                return False

            # verify if the proof of work is correct
            if not ZeroChain.proof_pow(block_headers[i]):
                return False

        # return True if all blcoks are fine
        return True
Beispiel #4
0
def ZeroMerkleTreeLite(items: list, size = None):
    if size is None: size = len(items)
    layer = [Hasher.raw_hash(items[x]) for x in range(size)]

    items = len(layer)
    while items > 1:
        for i in range(0, items - 1, 2):
            layer[i>>1] = Hasher.raw_hash(layer[i], layer[i + 1])
        if items & 1 == 1:  # move the last odd item to the upper layer
            layer[(items+1)>>1] = layer[items-1]
        items = (items+1)>>1

    # return the root
    if items == 1:
        return layer[0]
    else:
        return b""
Beispiel #5
0
 def proof_pow(block_header):
     """
     Validates the block_header
     :param block_header:
     :returns True if the block_header is a valid pow.
     """
     difficulty = block_header.difficulty
     return Hasher.object_hash(block_header)[:difficulty] == "0" * difficulty
Beispiel #6
0
def LibraMerkleTreeLite(items: list, size = None):
    if size is None: size = len(items)
    layer = [Hasher.raw_hash(items[x]) for x in range(size)]
    if len(layer) & 1 == 1:
        layer.append(b"")

    items = len(layer)
    while items > 1:
        if items & 1 == 1:
            layer[items] = b""
            items += 1
        for i in range(0, items, 2):
            layer[i>>1] = Hasher.raw_hash(layer[i], layer[i + 1])
        items = (items+1)>>1

    # return the root
    if items == 1:
        return layer[0]
    else:
        return b""
Beispiel #7
0
    def create_block(self):
        """
        Creates a block and include all transactions in self.pending_transactions.
        :returns the new created block_header
        """

        # create transaction merkle tree and get the root
        transaction_tree = ZeroMerkleTree(self.pending_transactions)
        transaction_root = transaction_tree.root_hash
        block_header = BlockHeader(height = self.block_height,
                                   previous_hash = Hasher.object_hash(self.latest_block),
                                   transaction_root = transaction_root,
                                   difficulty = self.difficulty,
                                   nonce = 0)
        self.pow_add_block(block_header)
        return block_header