def message(self, pubnub, message_object): print(f'\n-- Channel: {message_object.channel} | Message: {message_object.message}') if message_object.channel == CHANNELS['BLOCK']: block = Block.from_json(message_object.message) potential_chain = self.blockchain.chain[:] potential_chain.append(block) try: self.blockchain.replace_chain(potential_chain) self.transaction_pool.clear_blockchain_transactions( self.blockchain ) print('\n -- Successfully replaced the local chain') except Exception as e: print(f'\n -- Did not replace chain: {e}') elif message_object.channel == CHANNELS['TRANSACTION']: transaction = Transaction.from_json(message_object.message) self.transaction_pool.set_transaction(transaction) print('\n -- Set the new transaction in the transaction pool') elif message_object.channel == CHANNELS['ENERGY']: print("recived etran") etran = Etran.from_json(message_object.message) self.account.etranPool.append(etran) elif message_object.channel == CHANNELS['ETRANACK']: print("recived etran ack") etran = Etran.from_json(message_object.message) self.account.etranPoolAck.append(etran)
def is_valid_transaction_chain(chain): """ enforce the rules of a chain composed of blocks of transactions - each transaction must only appear once in a chain - only 1 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 == True: raise Exception('There can only be one mining reward per block!'+f' Check block with hash {block.hash}') has_mining_reward = True else: blockchain_history = Blockchain() blockchain_history.chain = chain[0:i] balance_history = Wallet.calculate_balance(blockchain_history,transaction.input['address']) if balance_history != transaction.input['amount']: raise Exception(f'Transaction {transaction.id} has an invalid input amount!') Transaction.is_valid_transaction(transaction)
def is_transaction_chain_valid(chain): """ Validate chain with blocks of transactions -- Only one reward per transaction. -- Each transaction must only apprear once in chain. """ transaction_ids = [] for i in range(len(chain)): block = chain[i] contains_mining_reward = False for transaction_json in block.data: transaction_obj = Transaction.from_json(transaction_json) if transaction_obj.id in transaction_ids: raise Exception( f"Transaction: {transaction_obj.id} is not unique") transaction_ids.append(transaction_obj.id) if transaction_obj.input == MINIING_REWARD_INPUT: if contains_mining_reward: raise Exception( f'Duplicate mining reward in block: {block.hash}') contains_mining_reward = True else: blockchain_tillnow = BlockChain() blockchain_tillnow.chain = chain[0:i] balance_tillnow = Wallet.calculate_balance( blockchain_tillnow, transaction_obj.input["address"]) if balance_tillnow != transaction_obj.input["amount"]: raise Exception( f"Transaction: {transaction_obj.id} has invalid input" ) Transaction.is_transaction_valid(transaction_obj)
def is_valid_transaction_chain(chain): 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( 'Transaction {transaction.id} has an invalid input amount' ) Transaction.is_valid_transaction(transaction)
def route_add_to_transaction_pool(): data = request.get_json() transaction_pool.add_transaction(Transaction.from_json(data)) response_data = {'message': 'Transaction added to pool', 'code': 'SUCCESS'} return make_response(jsonify(response_data), 201)
def message(self,pubnub,message_object): print(f'\n Incoming message_object:{message_object.channel} |Message:{message_object.message}') if message_object.channel==CHANNELS['BLOCK']: block=Block.from_json(message_object.message) potential_chain=self.blockchain.chain[:] potential_chain.append(block) try: self.blockchain.replace_chain(potential_chain) self.transaction_pool.clear_blockchain_transactions(self.blockchain) print('\n Successfully replaced the local chain') except Exception as e: print(f'\n Did not replace chain:{e}') elif message_object.channel==CHANNELS['TRANSACTION']: transaction=Transaction.from_json(message_object.message) self.transaction_pool.set_transaction(transaction) print('\n Set the new transaction in the transaction pool')
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 block in chain: 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.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 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: # Seperate the mining reward blocks from other blocks for amount validation 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)
def message(self, pubnub, msg_obj): print( f'\n-- Channel: {msg_obj.channel}\n-- Message: {msg_obj.message}') if msg_obj.channel == CHANNELS['BLOCK']: block = Block.from_json(msg_obj.message) potential_chain = self.blockchain.chain[:] potential_chain.append(block) try: self.blockchain.replace_chain(potential_chain) self.transaction_pool.clear_bc_transactions(self.blockchain) print(f'\n -- Successfully replaced the local chain.') except Exception as e: print(f'\n -- Could not replace the chain: {e}.') elif msg_obj.channel == CHANNELS['TRANSACTION']: trans = Transaction.from_json(msg_obj.message) self.transaction_pool.set_transaction(trans) print(f'\n -- Set the new transaction in the transaction pool')
def is_valid_transaction_chain(chain): """ Enforce the rules of the blockchain - Each transaction must only appear once int ge blockchain - There can only be one mining reward per block - Each transaction must be valid :param chain: :return: """ 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.input == MINING_REWARD_INPUT: if has_mining_reward: raise Exception( f"There can only be one mining reward in a block. Check block {block.hash}" ) has_mining_reward = True else: if transaction.id in transaction_ids: raise Exception( f"Transaction {transaction.id} is not unique") transaction_ids.add(transaction.id) 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)
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] 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' # ) AssetsTransaction.is_valid_transaction(transaction)
def is_valid_transaction_chain(chain): """ Enforce the rules of a chain compoesd of blocks of transactions. 1) Each transaction must only appear once in the chain. 2) There can only be one mining reward per block. 3) 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 this has: {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"The transaction {transaction.id} has an invalid input amount." ) Transaction.is_valid_transaction(transaction)
def is_valid_transaction_chain(chain): """ enforces the rules of a chain composed of blocks of transctions. - Each transaction must only appear once in a 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 duplicated') if transaction.input == MINING_REWARD_INPUT: if has_mining_reward: raise Exception('Invalid mining rewards'\ f'check with the hash: {block.hash}') has_mining_reward = True else: transaction_ids.add(transaction.id) 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)
def message(self, pubnub, message_object): print( f"Message: {message_object.message} on Channel: {message_object.channel}" ) if message_object.channel == CHANNELS['BLOCK']: block = Block.from_json(message_object.message) updated_chain = self.blockchain.chain[:] updated_chain.append(block) try: self.blockchain.replace_chain(updated_chain) self.transaction_pool.clear_transactions_added_to_blockchain( self.blockchain) print("Successfully Updated the chain!") except Exception as e: print(f"Chain update failed: {e}") elif message_object.channel == CHANNELS["TRANSACTION"]: transaction = Transaction.from_json(message_object.message) self.transaction_pool.add_transaction(transaction) print("\n -- Added new transaction to transaction pool")
def message(self, pubnub, message_object): print( f"\n-- Channel: {message_object.channel} | Message: {message_object.message}" ) if message_object.channel == CHANNELS["BLOCK"]: block = Block.from_json(message_object.message) potential_chain = self.blockchain.chain[:] potential_chain.append(block) try: self.blockchain.replace_chain(potential_chain) self.transaction_pool.clear_blockchain_transactions( self.blockchain) print(f"\n -- Successfully replaced the local chain") except Exception as e: print(f"\n -- Did not replace chain: {e}") elif message_object.channel == CHANNELS["TRANSACTION"]: transaction = Transaction.from_json(message_object.message) self.transaction_pool.set_transaction(transaction) print(f"\n -- Set the new transaction in the transaction pool")
def calculate_balance(self, blockchain): """ Updates wallet balance with the latest transaction """ balance = self.balance transactions = [] wallet_transactions = [] for block in blockchain.chain: for transaction in block.data: transaction = Transaction.from_json(transaction) transactions.append(transaction) for transaction in transactions: if transaction.input['address'] == self.address: wallet_transactions.append(transaction) start_time = 0 if len(wallet_transactions) > 0: latest_transaction = wallet_transactions[0] for wallet_transaction in wallet_transactions: if wallet_transaction.input[ 'timestamp'] > latest_transaction.input['timestamp']: latest_transaction = wallet_transaction balance = latest_transaction.outputs['sender_amount'] start_time = latest_transaction.input['timestamp'] for transaction in transactions: if transaction.input[ 'address'] == MINING_REWARD_INPUT or transaction.input[ 'timestamp'] > start_time: if transaction.outputs['recipient_address'] == self.address: balance += transaction.outputs['recipient_amount'] return balance
def is_valid_transaction_chain(chain): """ Enforce the rules of the chain composed of blocks of transactions. - Each transaction must only appear once per chain. - There can oly 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( f'Transaction {transaction.id} with block hash \'{block.hash}\': There can ' 'only be one mining reward per block.') 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)
def message(self, pubnub, message_obj): print( f'\n-- Channel: {message_obj.channel} || Message: {message_obj.message}' ) if message_obj.channel == CHANNELS['BLOCK']: block = Block.from_json(message_obj.message) new_chain = self.blockchain.chain[:] new_chain.append(block) try: self.blockchain.replace_chain(new_chain) self.transaction_pool.clear_blockchain_transactions( self.blockchain) print('\n -- Successfully replaced the local chain') except Exception as e: print(f'\n -- Did not replace chain: {e}') elif message_obj.channel == CHANNELS['TRANSACTION']: transaction = Transaction.from_json(message_obj.message) self.transaction_pool.add_transaction(transaction) print('\n -- Added new transaction to the transaction pool!')
def message(self, pubnub, message_object): print(f'\n Incoming Message : {message_object}') if message_object.channel == CHANNELS['BLOCK']: block = Block.from_json(message_object.message) print('Block to mine ', block) potential_chain = self.blockchain.chain # potential_chain.append(block) print(potential_chain) try: self.blockchain.replace_chain(potential_chain) self.transaction_pool.clear_blockchain_transactions( self.blockchain) print('Chain Replaced') except Exception as e: print(f'Did not replace" {e}') elif message_object.channel == CHANNELS['TRANSACTION']: transaction = Transaction.from_json(message_object.message) self.transaction_pool.set_transaction(transaction) print('New Transaction in Pool') elif message_object.channel == CHANNELS['ASSETS']: assetsTran = AssetsTransaction.from_json(message_object.message) self.assetPool.set_transaction(assetsTran) print('New Assets Transaction is added')
def is_valid_trans_chain(chain): ''' Enforce the rules of a chain composed of blocks of transaction. - Each transaction must only appear ONCE in the chain. - There can only be ONE mining reward per block. - Each transaction MUST be valid. ''' trans_ids = set() for i in range(len(chain)): block = chain[i] has_mining_reward = False for trans_json in block.data: trans = Transaction.from_json(trans_json) if trans.input == MINING_REWARD_INPUT: if has_mining_reward: raise Exception('There can only be one mining reward ' 'per block. Check block with hash: ' f'{block.hash}') has_mining_reward = True else: if trans.id in trans_ids: raise Exception( f'Transaction {trans.id} is not unique.') trans_ids.add(trans.id) historic_blockchain = Blockchain() historic_blockchain.chain = chain[0:i] historic_balance = Wallet.calculate_balance( historic_blockchain, trans.input['address']) if historic_balance != trans.input['amount']: raise Exception( f'Transaction {trans.id} has an invalid input amount.' ) Transaction.is_valid(trans)