Ejemplo n.º 1
0
    def test_proof_of_work_invalid_nonce(self):
        transactions_hash = self.mempool.hash([])
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = 12345

        self.assertFalse(
            ProofOfWork.valid_proof(transactions_hash, previous_block_hash,
                                    nonce))
Ejemplo n.º 2
0
    def test_proof_of_work(self):
        transactions_hash = self.mempool.hash([])
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)

        encoded = f'{transactions_hash}{previous_block_hash}{nonce}'.encode()
        hashed = hashlib.sha256(encoded).hexdigest()

        self.assertEqual(hashed[:4], '0000')
        self.assertTrue(
            ProofOfWork.valid_proof(transactions_hash, previous_block_hash,
                                    nonce))
Ejemplo n.º 3
0
    def valid_chain(self, chain):
        """
        Validate a given blockchain by checking the hash, the Proof of Work and the transactions for each block.
        :param chain: <list> The blockchain
        :return: <bool> True if valid, False if not
        """

        previous_block = chain[0]
        block_index = 1

        while block_index < len(chain):
            current_block = chain[block_index]

            # Validate the hash of the block
            if current_block['previous_block_hash'] != self.hash(
                    previous_block):
                return False

            # Validate the Proof of Work
            if not ProofOfWork.valid_proof(current_block['transactions_hash'],
                                           self.hash(previous_block),
                                           current_block['nonce']):
                return False

            # Validate the transactions of the block
            if current_block['transactions']:
                coinbase_transactions = 0
                for current_transaction in current_block['transactions']:
                    # Count the amount of coinbase transactions in the block
                    if current_transaction['sender'] == "0":
                        coinbase_transactions += 1
                    if not self.valid_transaction(current_transaction, chain,
                                                  block_index):
                        return False
                # If the block contains more than one coinbase transaction return False
                if coinbase_transactions > 1:
                    return False

            previous_block = current_block
            block_index += 1

        return True