def mine_block(self): response = { 'block': False, 'wallet': self.hosting_node_id is not None, } # Check wallet address. We can't mine without wallet address. if not self.hosting_node_id: response['message'] = 'Create or restore wallet' return response # Check chain sync with other peer nodes if self.resolve_conflicts: print('Blockchain has OLDER STATE. Need update node blockchain!') response['message'] = 'Blockchain has OLDER STATE. Update it!' return response # Check signatures opened transactions before adding to block for tx in self.__open_transactions: message = tx.sender + tx.recipient + str(tx.amount) if not Wallet.check_signature(tx.public_key, message, tx.signature): response[ 'message'] = f'Transaction to {tx.recipient} has bad signature' return response # Reward transaction for miners reward_transaction = Transaction( sender='MINING_REWARD_BOT', public_key='MINING_REWARD_BOT_PUBLIC_KEY', signature='MINING_REWARD_BOT_SIGNATURE', recipient=self.hosting_node_id, amount=MINING_REWARD) # Add reward transaction self.__open_transactions.append(reward_transaction) # IMPORTANT: Proof of Work should NOT INCLUDE REWARD TRANSACTION nonce = self.proof_of_work() # Create block block = Block(index=len(self.__chain), previous_hash=hash_block(self.__chain[-1]), transactions=self.__open_transactions[:], nonce=nonce) # Convert Block Object to dictionary block_dict = self.block_as_dict(block) # Broadcast new block to other nodes result = self.broadcast_to_other_nodes(block_dict) if result['ok']: # Add block to blockchain and save updated blockchain self.__chain.append(block) self.save_blockchain() # Clear open transactions and save updated self.__open_transactions.clear() self.save_open_transactions() response['block'] = block_dict response['message'] = f'Block successfuly added to blockchain' else: response['message'] = '\n'.join(result['errors']) return response