示例#1
0
class Block(Logger):
    """Block and header definition."""

    NONCE_SIZE = 4

    def __init__(self,
                 blockchain=None,
                 name='block',
                 height=0,
                 version=0,
                 coinbase=None,
                 corners=None,
                 timestamp=0,
                 previous_hash=pycryptonight.cn_slow_hash(b''),
                 nonce=(0).to_bytes(NONCE_SIZE, 'big')):
        super().__init__(f"{name} - {height} :")
        self.blockchain = blockchain
        self.version = version
        self.timestamp = timestamp
        self.previous_hash = previous_hash
        self.nonce = nonce
        self.coinbase = coinbase
        self._corners = [] if corners is None else corners
        self.merkle_tree = MerkleTree(self.corners, fast_hash)
        self.hash = self.get_hash()
        self.difficulty = 4

    @property
    def corners(self):
        return [self.coinbase] + self._corners

    def compute_tree(self, new_data=None):
        if new_data is None:
            self.merkle_tree = MerkleTree(self.corners, fast_hash)
        else:
            self.merkle_tree.extend(new_data)

    @property
    def header(self):
        res = self.version.to_bytes(2, 'big')
        res += self.timestamp.to_bytes(8, 'big')
        res += len(self.corners).to_bytes(3, 'big')
        res += bytes.fromhex(self.merkle_tree.merkle_root)
        res += self.previous_hash
        res += self.nonce
        return res

    def random_nonce(self):
        self.timestamp = time.time_ns()
        self.nonce = os.urandom(self.NONCE_SIZE)

    def mine(self, difficulty=None):
        difficulty = self.difficulty if difficulty is None else difficulty
        while int.from_bytes(self.get_hash(), 'big') >= (1 <<
                                                         (256 - difficulty)):
            self.log(f"new hash : {self.hash.hex()}")
            self.random_nonce()
        self.log(f"Mined !! : {self.hash.hex()}")

    def get_hash(self):
        self.hash = pycryptonight.cn_slow_hash(self.header, 4)
        return self.hash

# --------------- GENERATE FROM LIST TEST -------------------- #
print("\n--------------- GENERATE FROM LIST TEST --------------------")
# This test simulates accumulating nonces in a single list
# Instantiate empty list
data = []

# Initialize testing list
newData = ["aoibune", "24pot309grtjb", "poegijshbn", "oqfh8vyu", "0298f7gvublnk", "pq09483f7guvbl"]

# Instantiate empty Merkle tree for appending
listTree = MerkleTree(data, hashfunc)

# Add list data to merkle tree
listTree.extend(newData);

# Print MerkleTree
print("\nPrinting Merkle Tree")
beautify(listTree)
print("\nPrinting root")
print(listTree.merkle_root)
print("\nPrinting leaves")
print(listTree.leaves)

# Generate an audit proof for the string
print("\nGenerating audit proof for poegijshbn")
proof = listTree.get_proof('poegijshbn')
print("\nProof: ")
print(proof)
示例#3
0
class Block(Logger):
    """Block and header definition."""

    NONCE_SIZE = 4

    def __init__(self,
                 blockchain=None,
                 name: str = 'block',
                 height: int = 0,
                 version: int = 0,
                 coinbase: Corner = None,
                 corners: list = None,
                 timestamp=0,
                 previous_hash=pycryptonight.cn_slow_hash(b''),
                 nonce=(0).to_bytes(NONCE_SIZE, 'big')):
        """
        Initialises a Block instance.

        :param blockchain: Blockchain
        :param name: str
        :param height: int
        :param version: int
        :param coinbase: Corner
        :param corners: Corner list
        :param timestamp: int
        :param previous_hash: bytes
        :param nonce: bytes
        """
        super().__init__(f"{name} - {height} :")
        self.blockchain = blockchain
        self.version = version
        self.timestamp = timestamp
        self.previous_hash = previous_hash
        self.nonce = nonce
        self.coinbase = coinbase
        self._corners = [] if corners is None else corners
        self.merkle_tree = MerkleTree(self.corners, fast_hash)
        self.hash = self.get_hash()
        self.difficulty = 4

    @property
    def corners(self):
        """
        list of coinbase and other corners.

        :return: Corner list
        """
        return [self.coinbase] + self._corners

    def compute_tree(self, new_data=None):
        """
        Computes the Merkle Tree associated with the corners in the block.

        :param new_data: Corner list
        :return: None
        """
        if new_data is None:
            self.merkle_tree = MerkleTree(self.corners, fast_hash)
        else:
            self.merkle_tree.extend(new_data)

    @property
    def header(self):
        """
        Raw representation of block header based on the Discorn Protocol.

        :return: bytes
        """
        res = self.version.to_bytes(2, 'big')
        res += self.timestamp.to_bytes(8, 'big')
        res += len(self.corners).to_bytes(3, 'big')
        res += bytes.fromhex(self.merkle_tree.merkle_root)
        res += self.previous_hash
        res += self.nonce
        return res

    def random_nonce(self):
        """
        Generates a random nonce for this block. (Mining OP)

        :return: None
        """
        self.timestamp = time.time_ns()
        self.nonce = os.urandom(self.NONCE_SIZE)

    def mine(self, difficulty=None):
        """
        Mines the given block for the given difficulty.

        :param difficulty: int
        :return: None
        """
        difficulty = self.difficulty if difficulty is None else difficulty
        while int.from_bytes(self.get_hash(), 'big') >= (1 <<
                                                         (256 - difficulty)):
            self.log(f"new hash : {self.hash.hex()}")
            self.random_nonce()
        self.log(f"Mined !! : {self.hash.hex()}")

    def get_hash(self):
        """
        Calculates the block's hash.

        :return: bytes
        """
        self.hash = pycryptonight.cn_slow_hash(self.header, 4)
        return self.hash