Пример #1
0
    def receive_block(cls, block, proof_result, sender_node_url, tx_to_miner):
        last_block = Blockchain.fetch_last_block()

        if not proof_result.is_valid():
            raise InvalidReceivedBlockException()

        if last_block.block_id != block.previous_block_hash:
            if last_block.block_number < block.block_number:
                print('resolving conflicting...')
                cls._resolve_conflicts(sender_node_url)
            else:
                print('win conflict')
                raise TooShortReceivedBlockException()

        if last_block.block_id == block.previous_block_hash:
            Blockchain.create_block(block)

        UnconfirmedTxPool.transactions.clear()
        UnconfirmedTxPool.create_transaction(tx_to_miner)
Пример #2
0
 def fetch_unspent_tx_outputs_by_address(cls, request):
     address = request.get_json()['address']
     unspent_tx_outputs_in_blockchain = Blockchain.fetch_unspent_tx_outputs_by_address(
         address)
     result_tx_outputs = list(
         filter(
             lambda tx_o: tx_o.transaction_output_id not in
             UnconfirmedTxPool.list_spent_tx_output_ids(),
             unspent_tx_outputs_in_blockchain))
     return jsonify(result_tx_outputs), 200
Пример #3
0
    def _resolve_conflicts(cls, send_node_url):
        json = requests.get(send_node_url + '/blocks').json()
        send_node_blocks = list(
            map(lambda block_dict: decode_block(block_dict), json))
        my_node_blocks = Blockchain.fetch_all_blocks()

        forked_block_number = cls._search_forked_block_number(
            send_node_blocks, my_node_blocks)
        deleting_blocks = list(
            filter(lambda block: block.block_number > forked_block_number,
                   my_node_blocks))
        adding_blocks = list(
            filter(lambda block: block.block_number > forked_block_number,
                   send_node_blocks))

        for deleting_block in deleting_blocks:
            Blockchain.delete_block(deleting_block)

        for adding_block in adding_blocks:
            Blockchain.create_block(adding_block)
Пример #4
0
    def create_transaction(cls, tx_request):
        # 使用としているトランザクションアウトプットIDが既に未承認のトランザクションアウトプットIDに含まれていたら例外を投げる
        spent_tx_output_ids_in_unconfirmed_tx_pool = UnconfirmedTxPool.list_spent_tx_output_ids()
        tx_request.assert_unspent_tx_output_ids(spent_tx_output_ids_in_unconfirmed_tx_pool)

        unspent_tx_outputs_in_blockchain = Blockchain.fetch_unspent_tx_outputs_by_tx_output_ids(
            tx_request.get_requesting_tx_output_ids())

        # 今回使用しようとしているトランザクションインプットを算出
        tx_inputs = tx_request.get_tx_inputs(unspent_tx_outputs_in_blockchain)

        TransactionInput.verify_tx_inputs(tx_inputs, tx_request.sender_address)

        transaction = Transaction.build_with_tx_outputs(
            timestamp = tx_request.timestamp,
            tx_inputs = tx_inputs,
            request_amount = tx_request.amount,
            sender_address = tx_request.sender_address,
            recipient_address = tx_request.recipient_address
        )

        UnconfirmedTxPool.transactions.append(transaction)

        return transaction
Пример #5
0
    def _create_block(cls):
        last_block = Blockchain.fetch_last_block()

        previous_hash = last_block.block_id
        block_number = Blockchain.fetch_block_count() + 1

        proof_of_work = ProofOfWork(previous_hash,
                                    last_block.difficulty_target)
        proof_result = proof_of_work.prove()

        proof_result.assert_valid()

        transactions = UnconfirmedTxPool.transactions.copy()
        UnconfirmedTxPool.transactions.clear()

        target_transactions = Blockchain.search_new_transactions(transactions)

        block = Block.build(
            block_number=block_number,
            previous_block_hash=previous_hash,
            timestamp=datetime.now().timestamp(),
            merkle_root="",  # TODO
            difficulty_target=last_block.difficulty_target,
            nonce=proof_result.nonce,
            transactions=target_transactions)

        last_block = Blockchain.fetch_last_block()
        if last_block.block_id != block.previous_block_hash:
            print('lost mining', block.block_id)
            raise LoseMiningException()

        Blockchain.create_block(block)
        print('block created', block.block_id)
        print('current block number', block.block_number)

        return block, proof_result
Пример #6
0
    def assert_new_block(cls, block_id):
        block = Blockchain.find_block(block_id)
        if block is not None:
            raise DuplicatedBlockException()

        return
Пример #7
0
 def fetch_all_blocks(cls):
     return jsonify(Blockchain.fetch_all_blocks()), 200