def mine_block(self): proof_of_work = self.get_proof_of_work() mining_reward_transaction = Transaction(MINING_SENDER, self.__node_pub_key, MINING_REWARD, None) self.__outstanding_transactions.append(mining_reward_transaction) new_block = Block( hash_block(self.get_last_block()), int(self.get_last_block().index) + 1, self.__outstanding_transactions, proof_of_work, ) self.__chain.append(new_block) # Check to see if any outstanding transactions have been tampered with after being saved for txn in self.__outstanding_transactions: if not Verification.verify_transaction(txn, self.get_balance): return False if Verification.verify_blockchain(self.__chain): global participants self.__outstanding_transactions = [] participants[self.__node_pub_key] = True self.save_data() return True self.__chain.pop() self.__outstanding_transactions.pop() return False
def proof_chain(self): print(' Offers checked.\n') if Verification.verify_chain(self.blockchain.chain,check=True) and Verification.verify_chain(self.vote.chain) and Verification.verify_chain(self.voted.chain) and Verification.verify_chain(self.key.chain): print(' Transactions proofed.') print(' Votings proofed.') print(' Votes proofed.') print(' Keys proofed.') print('----------------------------------------')
def listen_for_input(self): waiting_for_input = True while waiting_for_input: print('choices!') print('1: add transaction') print('2: mine block') print('3: display blocks') print('4: validate transactions') print('5: create wallet') print('6: load wallet') print('7: save keys') print('q: quit') user_choice = self.get_user_choice() if user_choice == '1': tx_data = self.get_transaction_value() recipient, amount = tx_data signature = self.wallet.sign_transaction( self.wallet.public_key, recipient, amount) if self.blockchain.add_transaction(recipient, self.wallet.public_key, signature, amount=amount): print('transaction added') else: print('transaction failed :(') print(self.blockchain.get_open_transactions()) elif user_choice == '2': if not self.blockchain.mine_block(): print('mining failed. no wallet?') elif user_choice == '3': self.print_blockchain_elements() elif user_choice == '4': if Verification.verify_transactions(self.blockchain.get_open_transactions(), self.blockchain.get_balance): print('all transactions valid') else: print('there are invalid transactions') elif user_choice == '5': self.wallet.create_keys() self.blockchain = Blockchain(self.wallet.public_key) elif user_choice == '6': self.wallet.load_keys() self.blockchain = Blockchain(self.wallet.public_key) elif user_choice == '7': self.wallet.save_keys() elif user_choice == 'q': waiting_for_input = False else: print('input invalid, try again') if not Verification.verify_chain(self.blockchain.chain): self.print_blockchain_elements() print('blockchain invalid') break print('balance of {}: {:6.2f}'.format( self.wallet.public_key, self.blockchain.get_balance())) else: print('user complete') print('finished')
def listen_for_input(self): """Starts the node and waits for user input.""" waiting_for_input = True # A while loop for the user input interface # It's a loop that exits once waiting_for_input becomes False or when break is called while waiting_for_input: print('Please choose') print('1: Add a new transaction value') print('2: Mine a new block') print('3: Output the blockchain blocks') print('4: Check transaction validity') print('q: Quit') user_choice = self.get_user_choice() if user_choice == '1': tx_data = self.get_transaction_value() recipient, amount = tx_data # Add the transaction amount to the blockchain if self.blockchain.add_transaction(recipient, self.id, amount=amount): print('Added transaction!') else: print('Transaction failed!') print(self.blockchain.get_open_transactions()) elif user_choice == '2': self.blockchain.mine_block() elif user_choice == '3': self.print_blockchain_elements() elif user_choice == '4': if Verification.verify_transactions( self.blockchain.get_open_transactions(), self.blockchain.get_balance): print('All transactions are valid') else: print('There are invalid transactions') elif user_choice == 'q': # This will lead to the loop to exist because it's running condition becomes False waiting_for_input = False else: print('Input was invalid, please pick a value from the list!') if not Verification.verify_chain(self.blockchain.chain): self.print_blockchain_elements() print('Invalid blockchain!') # Break out of the loop break print('Balance of {}: {:6.2f}'.format( self.id, self.blockchain.get_balance())) else: print('User left!') print('Done!')
def proof_of_work(self): last_block = self.chain[-1] last_hash = hash_block(last_block) proof = 0 while not Verification.valid_proof(self.kind, last_hash, proof): proof += 1 return proof
def resolve(self): winner_chain = self.chain replace = False for node in self.__peer_nodes: url = 'http://{}/chain'.format(node) try: response = requests.get(url) node_chain = response.json() node_chain = [ Block(block['index'], block['previous_hash'], [ Transaction(tx['sender'], tx['recipient'], tx['signature'], tx['amount']) for tx in block['transactions'] ], block['proof'], block['timestamp']) for block in node_chain ] node_chain_length = len(node_chain) local_chain_length = len(winner_chain) if node_chain_length > local_chain_length and Verification.verify_chain( node_chain): winner_chain = node_chain replace = True except requests.exceptions.ConnectionError: continue self.resolve_conflicts = False self.chain = winner_chain if replace: self.__open_transactions = [] self.save_data() return replace
def add_transaction(self, recipient, sender, signature, amount=1.0, is_receiving=False): # if self.public_key == None: # return False transaction = Transaction(sender, recipient, signature, amount) if Verification.verify_transaction(transaction, self.get_balance): self.__open_transactions.append(transaction) self.save_data() if not is_receiving: for node in self.__peer_nodes: url = 'http://{}/broadcast-transaction'.format(node) try: response = requests.post(url, json={ 'sender': sender, 'recipient': recipient, 'amount': amount, 'signature': signature }) if response.status_code == 400 or response.status_code == 500: print('transaction failed') return False except requests.exceptions.ConnectionError: continue return True return False
def add_block(self, block): transactions = [ Transaction( tx['sender'], tx['recipient'], tx['signature'], tx['amount'], ) for tx in block['transactions'] ] proof_is_valid = Verification.valid_proof(transactions[:-1], block['previous_hash'], block['proof']) hashes_match = hash_block(self.chain[-1]) == block['previous_hash'] if not proof_is_valid or not hashes_match: return False converted_block = Block(block['index'], block['previous_hash'], transactions, block['proof'], block['timestamp']) self.__chain.append(converted_block) stored_transactions = self.__open_transactions[:] for itx in block['transactions']: for opentx in stored_transactions: if opentx.sender == itx['sender'] and opentx.recipient == itx[ 'recipient'] and opentx.amount == itx[ 'amount'] and opentx.signature == itx['signature']: try: self.__open_transactions.remove(opentx) except ValueError: print('item removed already') self.save_data() return True
def resolve(self): winner_chain = self.chain replace = False for node in self.__peer_nodes: url = "http://{}/chain".format(node) try: response = requests.get(url) node_chain = response.json() node_chain = [JBlock(block["index"], block["previous_hash"], [Transaction(transaction["sender"], transaction["recipient"], transaction["signature"], transaction["amount"]) for transaction in block["transactions"]], block["proof"], block["timestamp"]) for block in node_chain] node_chain_lenght = len(node_chain) local_chain_lenght = len(self.chain) if node_chain_lenght > local_chain_lenght and Verification.validate_j_chain(node_chain): winner_chain = node_chain replace = True except requests.exceptions.ConnectionError: continue self.resolve_conflicts = False self.chain = winner_chain if replace: self.open_transactions = [] FileHandler.save_j_chain(self) return replace
def add_block(self, block): transactions = [ Transaction(tx[sender_str], tx[recipient_str], tx[signature_str], tx[amount_str]) for tx in block[transactions_str] ] proof_is_valid = Verification.valid_proof(transactions[:-1], block[previous_hash_str], block[proof_str]) hashes_match = hash_block(self.chain[-1]) == block[previous_hash_str] if not proof_is_valid or not hashes_match: return False converted_block = Block(block[index_str], block[previous_hash_str], block[proof_str], transactions, block[timestamp_str]) self.__chain.append(converted_block) stored_transaction = self.__open_transactions[:] for itx in block[transactions_str]: for opentx in stored_transaction: if opentx.sender == itx[sender_str] and opentx.recipient == itx[recipient_str] and opentx.amount == \ itx[amount_str] and opentx.signature == itx[signature_str]: try: self.__open_transactions.remove(opentx) except ValueError: print('item is removed') self.save_data() return True
def add_transaction(self, sender, recipient, signature, amount, broadcast=False): # if self.node is None: # return False transaction = Transaction(sender, recipient, signature, amount) if Wallet.verify_signture(transaction): if Verification.verify_transaction(transaction, sender, self.get_balance): self.open_transactions.append(transaction) FileHandler.save_j_chain(self) if not broadcast: for node in self.__peer_nodes: url = "http://{}/broadcast-transaction".format(node) try: response = requests.post(url, json={"sender":sender, "recipient":recipient, "amount":amount, "signature":signature}) if response.status_code == 400 or response.status_code == 500: print("Transaction declined, needs resolving") return False except requests.exceptions.ConnectionError: continue return True else: print("This Transaction is not possible, as it exceeds your balance!") return False else: print("The Signature of this transaction is not valid") return False return True
def proof_of_work(self): last_block = self.__chain[-1] last_hash = hash_block(last_block) proof = 0 while not Verification.valid_proof(self.__open_transactions, last_hash, proof): proof += 1 return proof
def proof_of_work(self, transaction): # -1 for last block last_block = self.__chain[-1] last_hash = hash_block(last_block) proof = 0 # just increase nonce for valid_proof while not Verification.valid_proof(transaction, last_hash, proof): proof += 1 return proof
def proof_of_work(self): """Generate a proof of work for the open transactions, the hash of the previous block and a random number (which is guessed until it fits).""" last_block = self.__chain[-1] last_hash = hash_block(last_block) proof = 0 # Try different PoW numbers and return the first valid one while not Verification.valid_proof(self.__open_transactions, last_hash, proof): proof += 1 return proof
def get_proof_of_work(self): proof_of_work = 0 while not Verification.valid_proof_of_work( hash_block(self.get_last_block()), self.__outstanding_transactions, proof_of_work, ): proof_of_work += 1 return proof_of_work
def add_transaction(self, sender, recepient, amount, signature): global participants transaction = Transaction(sender, recepient, amount, signature) if Verification.verify_transaction(transaction, self.get_balance): self.__outstanding_transactions.append(transaction) participants[sender] = True participants[recepient] = True self.save_data() return True return False
def add_transaction(self, recipient, sender, kind, amount=1.0, check=True): if sender == 'MINING' or sender == 'TRADE': check = False transaction = Transaction(sender, recipient, amount, kind) if check == True: if Verification.verify_transaction(transaction, self.balance(False)): self.kind.append(transaction) self.save_data() return True else: self.kind.append(transaction) self.save_data() return True return False
def add_transaction(self, recipient, sender, signature, amount=1.0, is_receiving=False): """ Adds a transaction to the chain Arguments: :sender: sender of transaction (default owner) :recipent: recipent of transaction :amount: amount of transaction (default 1.0) """ # transaction = { # 'sender': sender, # 'recipient': recipient, # 'amount': amount} # dictionary key value pair sender is key # check if we have wallet or not, If not we cant add transaction if self.public_key is None: return False # using a ordered dictionary instead # our key value pair becomes tuples instead transaction = Transaction(sender, recipient, signature, amount) # if verify transaction successds then do following if Verification.verify_transaction(transaction, self.get_balance): self.__open_transactions.append( transaction) # storing above transactions self.save_data() if not is_receiving: for node in self.__peer_nodes: url = 'http://{}/broadcast-transaction'.format(node) try: response = requests.post(url, json={ 'sender': sender, 'recipient': recipient, 'amount': amount, 'signature': signature }) if (response.status_code == 400 or response.status_code == 500): print('transaction failed, resolve please') return False except requests.exceptions.ConnectionError: continue return True return False
def listen_for_input(self): start = True quit_j_chain = self.load_or_create_wallet() while not quit_j_chain: if start: self.print_possibilities() start = False decision = self.get_user_decision() if decision == "Q": # quit quit_j_chain = True self.print_j_chain_elements() elif decision == "T": # transaction if self.wallet.public_key is None: print( "You got no wallet, please load (L) or create (W) one." ) else: recipient, amount = self.get_transaction_input() signature = self.wallet.sign_transaction( self.wallet.public_key, recipient, amount) self.j_chain.add_transaction(self.wallet.public_key, recipient, signature, amount) elif decision == "M": # mine block if self.wallet.public_key is None: print( "You got no wallet, please load (L) or create (W) one." ) else: self.j_chain.mine_block() elif decision == "P": # Participants print([ participant + ": " + str(self.j_chain.get_balance(participant)) for participant in self.participants ]) else: print("This action is not available!") if not Verification.validate_j_chain(self.j_chain.chain): break
def add_transaction(self, recipient, sender, amount=1.0): """ Append a new value as well as the last blockchain value to the blockchain. Arguments: :sender: The sender of the coins. :recipient: The recipient of the coins. :amount: The amount of coins sent with the transaction (default = 1.0) """ # transaction = { # 'sender': sender, # 'recipient': recipient, # 'amount': amount # } transaction = Transaction(sender, recipient, amount) if Verification.verify_transaction(transaction, self.get_balance): self.__open_transactions.append(transaction) self.save_data() return True return False
def add_transaction(self, recipient, sender, signature, amount=1.0): """ Append a new value as well as the last blockchain value to the blockchain. Arguments: :sender: The sender of the coins :recipient: The recipient of the coins :amount: The amount of coins to send (default=1.0) """ if self.hosting_node_id is None: return False transaction = Transaction(sender, recipient, signature, amount) if Verification.verify_transaction(transaction, self.get_balance): self.__open_transactions.append(transaction) self.save_data() return True return False
def add_block(self, block): transactions = [Transaction(transaction["sender"], transaction["recipient"], transaction["signature"], transaction["amount"]) for transaction in block["transactions"]] proof_is_valid = Verification.check_valid_proof(transactions[:-1], block["previous_hash"], block["proof"]) hashes_match = hash_util.hash_block(self.chain[-1]) == block["previous_hash"] if not proof_is_valid or not hashes_match: return False converted_block = JBlock(block["index"], block["previous_hash"], transactions, block["proof"], block["timestamp"]) self.__chain.append(converted_block) stored_transactions = self.open_transactions[:] for incoming in block["transactions"]: for open_transaction in stored_transactions: sender_and_recipient_equal = open_transaction.sender == incoming["sender"] and open_transaction.recipient == incoming["recipient"] signature_equal = open_transaction.signature == incoming["signature"] amount_equal = open_transaction.amount == incoming["amount"] if sender_and_recipient_equal and signature_equal and amount_equal: try: self.open_transactions.remove(open_transaction) except ValueError: print("item already removed") FileHandler.save_j_chain(self) return True
def add_transaction(self, sender_, recipient_, signature, amount_=0.0, receiving=False): if self.public_key is None: return False # transaction = {'sender': sender_, # 'recipient': recipient_, # 'amount': amount_ # } transaction = Transaction(sender_, recipient_, signature, amount_) # verifying transaction before adding in open transaction if Verification.verify_transaction(transaction, self.get_balance): self.__open_transactions.append(transaction) # saving transaction in blockchain external hard drive # if transaction is added in open_transaction and not mine self.save_data() if not receiving: for node in self.__peer_node: url = 'http://{}/broadcast-transaction'.format(node) try: response = requests.post(url, json={ sender_str: sender_, recipient_str: recipient_, amount_str: amount_, signature_str: signature }) if response.status_code == 400 or response.status_code == 500: print('Transaction declined needs resolving') return False except requests.exceptions.ConnectionError: continue return True return False
def proof_of_work(self, hash_value): nounce = 0 while not Verification.check_valid_proof(self.open_transactions, hash_value, nounce): nounce += 1 return nounce
def listen_for_input(self): # split this while loop up in other function. waiting_for_input = True # validate letters as well. while waiting_for_input: print('Please choose: ') print('1: add transaction') print('2: mine new block') print('3: output blockchain') print('4: Check transaction validity') print('5: Create Wallet') print('6: Load Wallet') print('7: Save Keys') print('h: Manipulate Chain') print('0: quit') user_choice = self.get_user_choice() print(user_choice) if user_choice == '1': tx_data = self.get_transaction_value() recipient, amount = tx_data # just add a if to check if success as under signature = self.wallet.sign_transaction( self.wallet.public_key, recipient, amount) if self.blockchain.add_transaction(recipient, self.wallet.public_key, signature, amount=amount): print('Added transaction successful') else: print('transaction failed') print('Open Transactions: ' + str(self.blockchain.get_open_transactions())) elif user_choice == '2': if not self.blockchain.mine_block(): print('Mining Failed. Create a wallet') elif user_choice == '3': print('you picked 3') self.print_blockchain_elements() # elif user_choice == '4': # print(participants) elif user_choice == '4': if Verification.verify_transactions( self.blockchain.get_open_transactions(), self.blockchain.get_balance): print('All transactions valid') else: print('some invalid transactions') # elif user_choice == 'h': # if len(blockchain) >= 1: # blockchain[0] = { # 'previous_hash': '', # 'index': 0, # 'transactions': [{'sender': 'Marco', # 'recipient': 'polo', 'amount': 1000}] # } # print('picked h') elif user_choice == '5': # create wallet # self.wallet = Wallet() self.wallet.create_keys() self.blockchain = Blockchain(self.wallet.public_key, port) # self.blockchain = Blockchain(self.wallet.public_key) elif user_choice == '6': # load wallet self.wallet.load_keys() self.blockchain = Blockchain(self.wallet.public_key, port) # self.blockchain = Blockchain(self.wallet.public_key) elif user_choice == '7': # load wallet self.wallet.save_keys() elif user_choice == '0': # break waiting_for_input = False # break to quit or use continue to exit the loop. # continue skips rest of the loop code. else: print('invalid input') if not Verification.verify_chain(self.blockchain.chain): self.print_blockchain_elements() print('invalid chain') break print('Balance of {0}: {1:6.2f}'.format( self.wallet.public_key, self.blockchain.get_balance())) # Better formatting by string formatting print('Closed!')