Пример #1
0
def test_calculate_balance():
    blockchain = Blockchain()
    wallet = Wallet()

    assert Wallet.calculate_balance(blockchain,
                                    wallet.address) == STARTING_BALANCE

    amount = 50
    transaction = Transaction(wallet, 'recipient', amount)
    blockchain.add_block([transaction.to_json()])

    assert Wallet.calculate_balance(
        blockchain, wallet.address) == STARTING_BALANCE - amount

    received_amount_1 = 25
    received_transaction_1 = Transaction(Wallet(), wallet.address,
                                         received_amount_1)

    received_amount_2 = 77
    received_transaction_2 = Transaction(Wallet(), wallet.address,
                                         received_amount_2)

    blockchain.add_block(
        [received_transaction_1.to_json(),
         received_transaction_2.to_json()])

    assert Wallet.calculate_balance(blockchain, wallet.address) == \
        STARTING_BALANCE - amount + received_amount_1 + received_amount_2
Пример #2
0
    def is_valid_transaction_chain(chain):
        """
        Enforce the rules of a chain composed of blocks of transactions:
        - Each transaction must only appear once in the chain.
        - There can only be one mining reward per block.
        - Each transaction must be valid.
        """
        transaction_ids = set()

        for i in range(len(chain)):
            block = chain[i]
            has_mining_reward = False

            for transaction_json in block.data:
                transaction = Transaction.from_json(transaction_json)

                if transaction.id in transaction_ids:
                    raise Exception(
                        f'Transaction {transaction.id} is not unique.')
                transaction_ids.add(transaction.id)

                if transaction.input == MINING_REWARD_INPUT:
                    if has_mining_reward:
                        raise Exception('There can only be one mining reward per block. '\
                            f'Check block with hash: {block.hash}')
                    has_mining_reward = True
                else:
                    historic_blockchain = Blockchain()
                    historic_blockchain.chain = chain[0:i]

                    historic_balance = Wallet.calculate_balance(
                        historic_blockchain, transaction.input['address'])
                    if historic_balance != transaction.input['amount']:
                        raise Exception(f'Transaction {transaction.id} has an invalid '\
                                'input amount')

                Transaction.is_valid_transaction(transaction)