Exemple #1
0
    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