def test_invalid_chain_transactions(self): # Mine 10 coins to initial_address coinbase_transaction = { 'sender': '0', 'recipient': self.initial_address, 'amount': 10 } transactions_hash = self.mempool.hash([coinbase_transaction]) previous_block_hash = self.blockchain.hash(self.blockchain.last_block) nonce = ProofOfWork.proof_of_work(transactions_hash, previous_block_hash) self.blockchain.create_block(nonce, previous_block_hash, [coinbase_transaction]) # Include a transaction in block with to much coins spent signed_transaction = self.wallet.sign_transaction( self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 100) self.mempool.current_transactions.append(signed_transaction) transactions_hash = self.mempool.hash( self.mempool.current_transactions) previous_block_hash = self.blockchain.hash(self.blockchain.last_block) nonce = ProofOfWork.proof_of_work(transactions_hash, previous_block_hash) self.blockchain.create_block(nonce, previous_block_hash, self.mempool.current_transactions) self.assertFalse(self.blockchain.valid_chain(self.blockchain.chain))
def mine(): # Create a coinbase transaction to collect the block reward (10 coins) the address of the sender has to be "0" coinbase_transaction = { 'sender': '0', 'recipient': wallet.addresses[0], 'amount': 10, 'signature': 'coinbase transaction' } # Include all transactions of the mempool in the next block including the coinbase transaction transactions_of_block = blockchain.mempool.current_transactions transactions_of_block.append(coinbase_transaction) # Run the Proof of Work algorithm to find a valid nonce for the block previous_block = blockchain.last_block previous_block_hash = blockchain.hash(previous_block) transactions_hash = blockchain.mempool.hash(transactions_of_block) nonce = ProofOfWork.proof_of_work(transactions_hash, previous_block_hash) # Create the new block block = blockchain.create_block(nonce, previous_block_hash, transactions_of_block) response = { 'message': "New block added to the chain", 'index': block['index'], 'timestamp': block['timestamp'], 'nonce': block['nonce'], 'transactions_hash': block['transactions_hash'], 'previous_block_hash': block['previous_block_hash'], 'transactions': block['transactions'] } return jsonify(response), 200
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))
def test_valid_chain(self): signed_transaction = self.wallet.sign_transaction( self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0) self.mempool.add_transaction(signed_transaction, self.blockchain) transactions_hash = self.mempool.hash( self.mempool.current_transactions) previous_block_hash = self.blockchain.hash(self.blockchain.last_block) nonce = ProofOfWork.proof_of_work(transactions_hash, previous_block_hash) self.blockchain.create_block(nonce, previous_block_hash, self.mempool.current_transactions) self.assertTrue(self.blockchain.valid_chain(self.blockchain.chain))
def test_block_hash(self): signed_transaction = self.wallet.sign_transaction( self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0) self.mempool.add_transaction(signed_transaction, self.blockchain) transactions_hash = self.mempool.hash( self.mempool.current_transactions) previous_block_hash = self.blockchain.hash(self.blockchain.last_block) nonce = ProofOfWork.proof_of_work(transactions_hash, previous_block_hash) self.blockchain.create_block(nonce, previous_block_hash, self.mempool.current_transactions) created_block = self.blockchain.last_block block_encoded = json.dumps(created_block, sort_keys=True).encode() block_hash = hashlib.sha256(block_encoded).hexdigest() self.assertEqual(len(self.blockchain.hash(created_block)), 64) self.assertEqual(self.blockchain.hash(created_block), block_hash)
def test_invalid_chain_prev_block_hash(self): signed_transaction = self.wallet.sign_transaction( self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0) transactions_hash = self.mempool.hash( self.mempool.current_transactions) previous_block_hash = self.blockchain.hash(self.blockchain.last_block) nonce = ProofOfWork.proof_of_work(transactions_hash, previous_block_hash) block = { 'index': len(self.chain) + 1, 'timestamp': time(), 'nonce': nonce, 'transactions_hash': transactions_hash, 'previous_block_hash': '12345', 'transactions': [signed_transaction] } self.blockchain.chain.append(block) self.assertFalse(self.blockchain.valid_chain(self.blockchain.chain))
def test_invalid_chain_coinbase_transaction_amount(self): coinbase_transaction = { 'sender': '0', 'recipient': self.initial_address, 'amount': 100 } transactions_hash = self.mempool.hash([coinbase_transaction]) previous_block_hash = self.blockchain.hash(self.blockchain.last_block) nonce = ProofOfWork.proof_of_work(transactions_hash, previous_block_hash) block = { 'index': len(self.chain) + 1, 'timestamp': time(), 'nonce': nonce, 'transactions_hash': transactions_hash, 'previous_block_hash': previous_block_hash, 'transactions': [coinbase_transaction] } self.blockchain.chain.append(block) self.assertFalse(self.blockchain.valid_chain(self.blockchain.chain))
def test_create_block(self): signed_transaction = self.wallet.sign_transaction( self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0) self.mempool.add_transaction(signed_transaction, self.blockchain) transactions_hash = self.mempool.hash( self.mempool.current_transactions) previous_block_hash = self.blockchain.hash(self.blockchain.last_block) nonce = ProofOfWork.proof_of_work(transactions_hash, previous_block_hash) self.blockchain.create_block(nonce, previous_block_hash, self.mempool.current_transactions) created_block = self.blockchain.last_block self.assertEqual(len(self.blockchain.chain), 2) self.assertEqual(created_block, self.blockchain.chain[-1]) self.assertEqual(created_block['index'], 2) self.assertIsNotNone(created_block['timestamp']) self.assertEqual(created_block['nonce'], nonce) self.assertEqual(created_block['transactions_hash'], transactions_hash) self.assertEqual(created_block['previous_block_hash'], previous_block_hash) self.assertEqual(created_block['transactions'], [signed_transaction]) self.assertEqual(len(self.mempool.current_transactions), 0)