コード例 #1
0
def test_blockchain_valid_transaction_duplicate_rewardss():
    blockchain = Blockchain()
    transaction = Transactions(Wallet(), 'recipient', 100).to_json()
    reward_transaction = Transactions.transaction_reward(Wallet()).to_json()
    blockchain.add_block([transaction, reward_transaction, reward_transaction])
    with pytest.raises(Exception, match="has multiple rewards"):
        Blockchain.is_chain_transaction_valid(blockchain.chain)
コード例 #2
0
def test_transactions_validate_invalid_rewards():
    miner_wallet = Wallet()
    reward_transaction = Transactions.transaction_reward(miner_wallet)
    reward_transaction.output[miner_wallet.address] = 100
    reward_transaction.output['recp1'] = 100
    with pytest.raises(Exception, match="Invalid transaction reward"):
        Transactions.verify_transaction(reward_transaction)
コード例 #3
0
def test_wallet_balance_amount():
	wallet = Wallet()
	blockchain = Blockchain()
	amount = 34
	tr1 = Transactions(wallet, 'recp1', amount)
	blockchain.add_block([tr1.to_json()])
	assert Wallet.calculate_balance(blockchain, wallet.address) == STARTING_BALANCE - amount
コード例 #4
0
def blockchain():
    blockchain = Blockchain()
    for i in range(3):
        miner_wallet = Wallet()
        transaction = Transactions(Wallet(), 'recipient', i)
        reward_transaction = Transactions.transaction_reward(miner_wallet)
        blockchain.add_block([transaction.to_json()])
        return blockchain
コード例 #5
0
def test_blockchain_valid_transaction_incorrect_historical_balance(blockchain):
    wallet = Wallet()
    bad_transaction = Transactions(wallet, 'recipient', 1)
    bad_transaction.output[wallet.address] = 9000
    bad_transaction.input['amount'] = 9001
    bad_transaction.input['signature'] = wallet.sign(bad_transaction.output)
    blockchain.add_block([bad_transaction.to_json()])
    with pytest.raises(Exception, match="did not have the correct balance"):
        Blockchain.is_chain_transaction_valid(blockchain.chain)
コード例 #6
0
def make_transaction():
    transaction_json = request.get_json()
    #check if transaction exists
    transaction = transaction_pool.existing_transaction(wallet.address)
    if transaction:
        transaction.update_transaction(wallet, transaction_json['recipient'],
                                       transaction_json['amount'])
    else:
        transaction = Transactions(wallet, transaction_json['recipient'],
                                   transaction_json['amount'])

    #broadcast the transaction object
    pubsub.broadcast_transaction(transaction)
    return jsonify(transaction.to_json())
コード例 #7
0
def test_transaction_clear_transaction():
    transaction_pool = TransactionPool()
    transaction1 = Transactions(Wallet(), 'recp1', 10)
    transaction_pool.set_transaction(transaction1)
    blockchain = Blockchain()
    blockchain.add_block([transaction1.to_json()])
    # assert len(blockchain.chain) > 1
    print(transaction_pool.transaction_map)
    transaction_pool.clear_transaction(blockchain)
    assert transaction1.id not in transaction_pool.transaction_map.keys()
    # for index, block in enumerate(blockchain.chain):
    # 	if index == 0:
    # 		continue
    # 	for tdata in block.data:
    # 		# tdata = ast.literal_eval(tdata)
    # 		assert tdata['id'] == 'str'
コード例 #8
0
def mine_block():
    #get the transaction data and put it into the data field of add_block
    transaction_data = transaction_pool.transaction_data()
    #Append the transaction reward into the wallet of the miner
    transaction_reward = Transactions.transaction_reward(wallet).to_json()
    transaction_data.append(transaction_reward)
    blockchain.add_block(transaction_data)
    block = blockchain.chain[-1]
    #publish the block throughout the network to the subscribed channel
    pubsub.broadcast_block(block)
    #After everytime a block is mined, we need to clear the transaction pool.
    transaction_pool.clear_transaction(blockchain)
    return block.to_json(), 200
コード例 #9
0
    def is_chain_transaction_valid(chain):
        """
		Method to verify if each of the transactions in the chain is valid.
		Transaction is valid if:
		1. Each transation appears only once in the blockchain.
		2. There is only one reward transaction.
		3. The transaction is valid.
		"""
        transaction_ids = set()
        for index, block in enumerate(chain):
            if index == 0:
                continue
            has_reward_transaction = False
            for transaction_json in block.data:
                transaction = Transactions.from_json(transaction_json)
                if transaction.input == MINING_REWARD_INPUT:
                    if has_reward_transaction is True:
                        raise Exception(
                            "Transaction with id %s has multiple rewards" %
                            (transaction.id))
                    has_reward_transaction = True
                else:
                    #calculate historical balance using a historical balance
                    historical_chain = chain[:index]
                    historical_blockchain = Blockchain()
                    historical_blockchain.chain = historical_chain
                    #get the balance amount of the address
                    balance = Wallet.calculate_balance(
                        historical_blockchain, transaction.input['address'])
                    if balance != transaction.input['amount']:
                        raise Exception(
                            "Transaction id %s did not have the correct balance"
                            % (transaction.id))
                if transaction.id in transaction_ids:
                    raise Exception("Transaction with id %s is not unique" %
                                    (transaction.id))
                transaction_ids.add(transaction.id)
                Transactions.verify_transaction(transaction)
コード例 #10
0
 def message(self, pubnub, message_object):
     print('Message channel: %s | Message object: %s' %
           (message_object.channel, message_object.message))
     #check if a block was received through the BLOCK channel and then add it to the chaina and then perform replace chain
     if message_object.channel == 'BLOCK':
         block = Block.from_json(message_object.message)
         potential_chain = self.blockchain.chain[:]
         #add received block to the chain
         potential_chain.append(block)
         #perform replace_chain operation
         try:
             self.blockchain.replace_chain(potential_chain)
             #After everytime a block is mined, we need to clear the transaction pool.
             self.transaction_pool.clear_transaction(self.blockchain)
             print("Chain replacement was successful")
         except Exception as e:
             print("Chain replacement was not successful: %s" % (e))
     elif message_object.channel == 'TRANSACTIONS':
         transaction = Transactions.from_json(message_object.message)
         self.transaction_pool.set_transaction(transaction)
コード例 #11
0
def test_update_same_recp_transactions_invalid():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    with pytest.raises(Exception, match="Amount greater than balance"):
        transactions.update_transaction(wallet, 'recp1', 901)
コード例 #12
0
@app.route('/transactions')
def get_all_transactions():
    transaction_data = transaction_pool.transaction_data()
    return jsonify(transaction_data)


ROOT_PORT = 5000
PORT = ROOT_PORT
if os.getenv('PEER'):
    PORT = random.randint(5001, 6000)
    result = requests.get("http://localhost:%s/blockchain" % (ROOT_PORT))
    result_blockchain = Blockchain.from_json(result.json())
    try:
        blockchain.replace_chain(result_blockchain)
        print("Chain replacement with root node was successful")
    except Exception as e:
        print("Chain replacement was not successful: %s" % (e))

#Seed a few data into the backend to help us evaluate the frontend design
if os.getenv('SEED'):
    for i in range(0, 10):
        blockchain.add_block(
            [Transactions(Wallet(),
                          Wallet().address, i).to_json()])
    for i in range(0, 10):
        transaction_pool.set_transaction(
            Transactions(Wallet(),
                         Wallet().address, i))

app.run(port=PORT)
コード例 #13
0
def test_transaction_pool():
    transaction_pool = TransactionPool()
    transaction1 = Transactions(Wallet(), 'recp1', 10)
    transaction_pool.set_transaction(transaction1)
    assert transaction1.id in transaction_pool.transaction_map.keys()
コード例 #14
0
def test_blockchain_valid_transaction_duplicate_transactions():
    blockchain = Blockchain()
    transaction = Transactions(Wallet(), 'recipient', 100).to_json()
    blockchain.add_block([transaction, transaction])
    with pytest.raises(Exception, match="is not unique"):
        Blockchain.is_chain_transaction_valid(blockchain.chain)
コード例 #15
0
def test_transactions_validate_reward():
    miner_wallet = Wallet()
    reward_transaction = Transactions.transaction_reward(miner_wallet)
    Transactions.verify_transaction(reward_transaction)
コード例 #16
0
def test_transactions_basic():
    wallet = Wallet()
    Transactions(wallet, 'recp1', 100)
コード例 #17
0
def test_transactions_reward():
    miner_wallet = Wallet()
    reward_transaction = Transactions.transaction_reward(miner_wallet)
    assert reward_transaction.output[miner_wallet.address] == MINING_REWARD
    assert reward_transaction.input == MINING_REWARD_INPUT
コード例 #18
0
def test_verify_transactions_invalid_signature():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    transactions.input['signature'] = Wallet().sign(transactions.output)
    with pytest.raises(Exception, match="Invalid Signature"):
        Transactions.verify_transaction(transactions)
コード例 #19
0
def test_verify_transactions_output_values_wrong():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    transactions.input['amount'] = 78
    with pytest.raises(Exception, match="Invalid output values"):
        Transactions.verify_transaction(transactions)
コード例 #20
0
def test_transactions_amt_greater_than_balance():
    wallet = Wallet()
    with pytest.raises(Exception, match="Amount greater than balance"):
        Transactions(wallet, 'recp1', 1001)
コード例 #21
0
def test_update_same_recp_transactions():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    transactions.update_transaction(wallet, 'recp1', 100)
コード例 #22
0
def test_verify_transactions():
    wallet = Wallet()
    transactions = Transactions(wallet, 'recp1', 100)
    Transactions.verify_transaction(transactions)
コード例 #23
0
    @staticmethod
    def calculate_balance(blockchain, address):
        """
		Method to calculate the balances of a Wallet given its address.
		If the wallet's address is in the transaction's input, then we set the balance to the amount in input field.
		If the wallet's address is in the transaction's output, then we add the value in output field to the balance. 
		"""
        balance = STARTING_BALANCE
        #handle the scenario where blockchain is None
        if blockchain is None:
            return balance
        for index, block in enumerate(blockchain.chain):
            if index == 0:
                continue
            for transaction in block.data:
                if transaction['input']['address'] == address:
                    balance = transaction['output'][address]
                elif address in transaction['output']:
                    balance = balance + transaction['output'][address]
        return balance


if __name__ == '__main__':
    from backend.wallet.transactions import Transactions
    from backend.blockchain.blockchain import Blockchain
    wallet = Wallet()
    blockchain = Blockchain()
    amount = 34
    tr1 = Transactions(wallet, 'recp1', amount)
    blockchain.add_block([tr1.to_json()])
    print(Wallet.calculate_balance(blockchain, wallet.address))