def mine_block(self): if self.public_key is None: return None last_block = self.__chain[-1] hashed_block = hash_block(last_block) proof = self.proof_of_work() reward_transaction = Transaction("MINING", self.public_key, '', MINING_REWARD) copied_transactions = self.__open_transactions[:] for transaction in copied_transactions: if not Wallet.verify_transaction(transaction): return None copied_transactions.append(reward_transaction) block = Block(hashed_block, len(self.__chain), copied_transactions, proof) self.__chain.append(block) self.__open_transactions = [] self.save_data() for node in self.__peer_nodes: dict_block = block.__dict__.copy() dict_block["transactions"] = [ tx.__dict__ for tx in dict_block["transactions"] ] url = f"http://{node}/broadcast-block" try: response = requests.post(url, json={"block": dict_block}) if response.status_code == 400 or response.status_code == 500: print("Block declined, needs resolving.") if response.status_code == 409: self.resolve_conflicts = True except requests.exceptions.ConnectionError: continue return block
def mine_block(self): """Create a new block and add open transactions to it.""" # Fetch the currently last block of the blockchain if self.hosting_node == None: return None last_block = self.__chain[-1] # Hash the last block (=> to be able to compare it to the stored hash value) hashed_block = hash_block(last_block) proof = self.proof_of_work() # Miners should be rewarded, so let's create a reward transaction # reward_transaction = { # 'sender': 'MINING', # 'recipient': owner, # 'amount': MINING_REWARD # } reward_transaction = Transaction("MINING", self.hosting_node, "", MINING_REWARD) # Copy transaction instead of manipulating the original open_transactions list # This ensures that if for some reason the mining should fail, we don't have the reward transaction stored in the open transactions copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return None copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_transactions = [] self.save_data() return block
def add_block(self, block): rezultate = [ Rezultat(rez['emitator'], rez['receptor'], rez['info_didactic'], rez['semnatura']) for rez in block['rezultate'] ] proof_valid = Verification.valid_proof(rezultate, block['previous_hash'], block['proof']) hashes_match = hash_block(self.chain[-1]) == block['previous_hash'] if not proof_valid or not hashes_match: return False bloc_convertit = Block(block['index'], block['previous_hash'], rezultate, block['proof'], block['timestamp']) self.__chain.append(bloc_convertit) stored_rezultate = self.__date_de_introdus[:] for dDI in block['rezultate']: for openDate in stored_rezultate: if openDate.emitator == dDI[ 'emitator'] and openDate.receptor == dDI[ 'receptor'] and openDate.semnatura == dDI[ 'semnatura']: try: self.__date_de_introdus.remove(openDate) except ValueError: print('Element deja eliminat') self.save_data() return True
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 was already removed') self.save_data() for node in self.__peer_nodes: url = 'http://{}/broadcast-block'.format(node) converted_block = block.__dict__.copy() converted_block['transactions'] = [ tx.__dict__ for tx in converted_block['transactions']] try: response = requests.post(url, json={'block': converted_block}) if response == 400 or response.status_code == 500: print('Block declined, needs resolving') if response.status_code == 409: self.resolve_conflicts = True except requests.exceptions.ConnectionError: continue return block
def mine_block(self): if self.hosting_node == None: return False last_bock = self.__chain[-1] hash_val = hash_block(last_bock) proof_of_work_number = self.proof_of_work() # print(hash_val) # add_transaction(sender='MINING', recipient=owner, amount=MINING_REWARD, reward_transaction=True) reward_transaction = Transaction(sender='MINING', recipient=self.hosting_node, amount=MINING_REWARD, signature='') copied_transactions = self.__open_transactions[:] if not all( [Wallet.verify_transaction(tx) for tx in copied_transactions]): print('Some transaction are invalid!') return False copied_transactions.append(reward_transaction) block = Block(index=len(self.__chain), previous_hash=hash_val, transactions=copied_transactions, proof=proof_of_work_number) self.__chain.append(block) self.__open_transactions = [] self.save_data() return True
def mine_block(self): if self.public_key == None: return None last_block = self.__chain[-1] # Hash the last block. So, we can compare it to the stored hash value hashed_block = hash_block(last_block) proof = self.proof_of_work() # reward_transaction is created because miners should be added for mining a new block reward_transaction = Transaction( 'MINING', self.public_key, '', MINING_REWARD) # Copy transaction instead of manipulating the original open_transactions list # This ensures that if for some reason the mining should fail, we don't have the reward transaction stored in the open transactions copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return None copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_transactions = [] self.save_data() for node in self.__peer_nodes: url = 'http://{}/broadcast-block'.format(node) converted_block = block.__dict__.copy() converted_block['transactions'] = [ tx.__dict__ for tx in converted_block['transactions']] try: response = requests.post(url, json={'block': converted_block}) if response.status_code == 400 or response.status_code == 500: print('Block declined, needs resolving') except requests.exceptions.ConnectionError: continue return block
def mine_block(self): """Create a new block and add open transactions to it.""" if self.public_key is None: return None last_block = self.__chain[-1] hashed_block = hash_block(last_block) proof = self.proof_of_work() reward_transaction = Transaction('MINING', self.public_key, '', MINING_REWARD) copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return None copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_transactions = [] self.save_data() for node in self.__peer_nodes: url = 'http://{}/broadcast-block'.format(node) converted_block = block.__dict__.copy() converted_block['transactions'] = [ tx.__dict__ for tx in converted_block['transactions'] ] try: response = requests.post(url, json={'block': converted_block}) if response.status_code == 400 or response.status_code == 500: print('Block declined, needs resolving') if response.status_code == 409: self.resolve_conflicts = True except requests.exceptions.ConnectionError: continue return block
def add_block(self, block): transactions = [ Trax(tx['tx_sender'], tx['tx_recipient'], tx['signature'], tx['tx_amount']) for tx in block['trax'] ] proof_is_valid = VerficationHelper.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) # remove open transactions that has been added in the block stored_transactions = self.__open_trax[:] for itx in block['trax']: for opentx in stored_transactions: if opentx.tx_sender == itx[ 'tx_sender'] and opentx.tx_recipient == itx[ 'tx_recipient'] and opentx.tx_amount == itx[ 'tx_amount'] and opentx.signature == itx[ 'signature']: try: self.__open_trax.remove(opentx) except ValueError: print('Item was already removed') self.save_data() return True
def add_block(self, block): """Add a block which was received via broadcasting to the local blockchain.""" # Create a list of transaction objects transactions = [Transaction( tx['sender'], tx['recipient'], tx['signature'], tx['amount']) for tx in block['transactions']] # Validate the proof of work of the block and store the result (True or False) in a variable proof_is_valid = Verification.valid_proof( transactions[:-1], block['previous_hash'], block['proof']) # Check if previous_hash stored in the block is equal to the local blockchain's last block's hash and store the result in a block hashes_match = hash_block(self.chain[-1]) == block['previous_hash'] if not proof_is_valid or not hashes_match: return False # Create a Block object converted_block = Block( block['index'], block['previous_hash'], transactions, block['proof'], block['timestamp']) self.__chain.append(converted_block) stored_transactions = self.__open_transactions[:] # Check which open transactions were included in the received block and remove them # This could be improved by giving each transaction an ID that would uniquely identify it 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 was already removed') self.save_data() return True
def add_block(self, block): transactions = [ Transaction(tx['sender'], tx['recipient'], tx['signature'], tx['amount'], tx['meomo']) for tx in block['transactions'] ] # check ours proof_is_valid = Verification.valid_proof(transactions[:-1], block['previous_hash'], block['proof']) # check peers hashes_match = hash_block(self.chain[-1]) == block['previous_hash'] if not proof_is_valid or not hashes_match: return False # block is still a dictionary, need to convert first converted_block = Block(block['index'], block['previous_hash'], transactions, block['proof'], block['timestamp']) self.__chain.append(converted_block) # update open transactions before saving data stored_transactions = self.__open_transactions[:] for incoming_tx in block['transactions']: for opentx in stored_transactions: if (opentx.sender == incoming_tx['sender'] and opentx.recipient == incoming_tx['recipient'] and opentx.amount == incoming_tx['amount'] and opentx.signature == incoming_tx['signature'] and opentx.memo == incoming_tx['memo']): try: self.__open_transactions.remove(opentx) except ValueError: print('Item was already removed.') self.save_data() return True
def add_block(self, block): transactions = [ Transaction(tx['sender'], tx['recipient'], tx['signature'], tx['amount']) for tx in block['transactions'] ] # Excluding the last transaction, because that is the "reward" transaction valid_proof = Verification.valid_proof(transactions[:-1], block['previous_hash'], block['proof']) hashes_match = hash_block(self.chain[-1]) == block['previous_hash'] if not valid_proof 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 was already removed') self.save_data() return True
def mine_block(self): if self.hosting_node == None: return False last_block = self.__chain[-1] hashed_block = hash_block(last_block) proof = self.proof_of_work() reward_transaction = Transaction('MINING', self.hosting_node,'', MINING_REWARD) # Copy transaction instead of manipulating the original open_transactions list # This ensures that if for some reason the mining should fail, we don't have the reward transaction stored in the open transactions copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return False copied_transactions.append(reward_transaction) block = Block(len(self.__chain),hashed_block,copied_transactions,proof) self.__chain.append(block) self.__open_transactions = [] self.save_data() return True
def mine_block(self): """ Create a new block and add open transactions to it. """ if self.public_key is None: return None last_block = self.__chain[-1] hashed_block = hash_block(last_block) proof = self.__get_proof_of_work() reward_transaction = Transaction('MINING', self.public_key, '', MINING_REWARD) copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return None copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_transactions = [] self.__save_data() self.__broadcast_block(block) return block
def add_block(self, block): # Validate block, check pow and store # Must convert transactions to a list, because verification expects data in that format. <dictionary to a list of transaction objects> 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'] ) #Passing in a list of all transactions of block being received when validating pow. #Avoid last block in chain as it contains the reward transaction and will invalidate it. # #Usually calculate pow before adding reward transaction (e.g. mine_block). # using [:-1] avoids using the reward transaction as part of the transactions used to validate the incoming pow which wont work. 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 all fields are equal it is the same transaction 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 was already removed.') self.save_data() return True
def mine_block(self): """ Create a new block and add open transactions to it :return: """ if self.hosting_node is None: return None # Fetch the currently last block of the blockchain last_block = self.__chain[-1] # Hash the last block (to be able to compare it to the stored hash value) hashed_block = hash_block(last_block) # print(hashed_block) proof = self.proof_of_work() # Miners should be reward , so we create a reward transaction reward_transaction = Transaction('MINING', self.hosting_node, '', MINING_REWARD) # Copy transaction instead of manipulating the original open_transactions copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return None copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_transactions = [] self.save_data() return block
def verify_chain(self, blockchain): # block_index = 0 # is_valid = True # print(blockchain) # for block_index in range(len(blockchain)): # if block_index == 0: # block_index += 1 # continue # elif blockchain[block_index][0] == blockchain[block_index-1]: # is_valid = True # else: # is_valid = False # break # block_index += 1 for (index, block) in enumerate(blockchain): if index == 0: continue if block.previous_hash != hash_block(blockchain[index - 1]): return False if not self.valid_proof(block.transactions[:-1], block.previous_hash, block.proof): print("Invalid proof") return False return True
def add_block(self, block): """Add a block received as dictionary to the blockchain.""" transactions = [ Transaction(tx['sender'], tx['recipient'], tx['signature'], tx['amount']) for tx in block['transactions'] ] proof_is_valid = verifier.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 was already removed") self.save_data() return True
def verify_chain(cls, blockchain): # # block_index= 0 # is_valid = True # for block_index in range (len(blockchain)): # if block_index == 0: # continue # elif blockchain[block_index][0] == blockchain[block_index - 1]: # is_valid = True # else: # is_valid = False # # break # # for block in blockchain: # # if block_index == 0: # # block_index += 1 # # continue # # elif block[0] == blockchain[block_index - 1]: # # is_valid = True # # else: # # is_valid = False # # break # # block_index =+ 1 # return is_valid for (index, block) in enumerate(blockchain): if index == 0: continue if block.previous_hash != hash_block(blockchain[index - 1]): return False if not cls.valid_proof(block.transactions[:-1], block.previous_hash, block.proof): print('Proof of work is invalid') return False return True
def verify_chain(cls, blockchain, POW_LEADING_ZEROS): """Verifies the blockchain and returns True if it is valid, False otherwise Arguments: :blockchain: The blockchain to verify """ for (index, block) in enumerate(blockchain): if index == 0: # Ignore the Genesis block. continue if block.previous_hash != hash_block(blockchain[index - 1]): # Fail verification, if the previous-hash stored in the block does not match # the actual hash of the previous block. print( f"ERROR: The previous-hash in block {index} does not match the actual hash" ) return False if not cls.valid_proof(block.transactions[:-1], block.previous_hash, block.proof, POW_LEADING_ZEROS): # Fail verification, if the proof-of-work is invalid, # i.e, it does not generate the required hash from the stored proof. # Ignore the last transaction in the transactions array, which is the mining reward print(f"ERROR: The proof-of-work in block {index} is invalid") return False # Verify the blockchain, if it did not fail anywhere in the previous loop return True
def add_block(self, block): transactions = [ Transaction(tx['sender'], tx['recipient'], tx['signature'], tx['amount']) for tx in block['transactions'] ] is_valid_prood = Verification.valid_proof(transactions[:-1], block['previous_hash'], block['proof']) hashes_match = hash_block(self.chain[-1]) == block['previous_hash'] if not is_valid_prood or not hashes_match: return False block_object = Block(block['index'], block['previous_hash'], transactions, block['proof'], block['timestamp']) self.__chain.append(block_object) # Make a copy becuaes we are manipkauting the original and dont wan to iterate on it open_trns = self.__open_transactions[:] # Could possibly refactor for better perfomance # Update the open trnasaction on the peer node when a new block is braodcast for incoming_trn in block['transactions']: for open_trn in open_trns: if (open_trn.sender == incoming_trn['sender'] and open_trn.recipient == incoming_trn['recipient'] and open_trn.amount == incoming_trn['amount'] and open_trn.signature == incoming_trn['signature']): try: self.__open_transactions.remove(open_trn) except ValueError: print("Item is already removed") self.save_data() return True
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: print('failed to validate', proof_is_valid, hashes_match) return False print('validated before adding') converted_block = Block(block['index'], block['previous_hash'], transactions, block['proof'], block['timestamp']) self.__chain.append(converted_block) stored_transaction = self.__open_transactions[:] for in_tx in transactions: for op_tx in stored_transaction: if in_tx.sender == op_tx.sender and in_tx.recipient == op_tx.recipient and in_tx.amount == op_tx.amount: try: self.__open_transactions.remove(op_tx) except ValueError: print('Value already removed') finally: break self.save_data() return True
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']) hashees_match = hash_block(self.chain[-1]) == block['previous_hash'] if not proof_is_valid or not hashees_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 já foi removido!') self.save_data() return True
def mine_block(self): last_block = self.__chain[-1] hashed_block = hash_util.hash_block(last_block) proof = self.proof_of_work() reward_tx = Transaction( 'MINING', self.public_key, MINING_REWARD, '') copied_transactions = self.open_tansactions for tx in copied_transactions: if not Wallet.verify_transaction(tx): return None copied_transactions.append(reward_tx) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_tansactions = [] self.save_data() # if not is_receiving: for node in self.__peer_nodes: try: self.__broadcast_block__(node, block) except (requests.exceptions.ConnectionError, BlockError) as error: print(error) continue return block
def mine_block(self): if self.public_key == None: return None last_block = self.__chain[-1] hashed_block = hash_block(last_block) proof = self.proof_of_work() reward_transaction = Transaction('MINING', self.public_key, '', MINING_REWARD) # [:] tells it to copy the entire list, not just to copy the reference to it in memory. Before the : you can add the starting index and the last index + 1 that you want copied. copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return None copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_transactions = [] self.save_data() for node in self.__peer_nodes: url = 'http://{}/broadcast-block'.format(node) converted_block = block.__dict__.copy() converted_block['transactions'] = [ tx.__dict__ for tx in converted_block['transactions'] ] try: response = requests.post(url, json={'block': converted_block}) if response.status_code == 400 or response.status_code == 500: print('Block declined, needs resolving.') except requests.exceptions.ConnectionError: continue return block
def add_block(self, block): transactions = [Transaction( tx['sender'], tx['recipient'], tx['amount'], tx['signature']) for tx in block['transactions']] proof_is_valid = Verification.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: raise BlockError() current_block = Block(block['index'], block['previous_hash'], transactions, block['proof'], block['timestamp']) self.__chain.append(current_block) stored_transactions = self.__open_tansactions[:] 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_tansactions.remove(opentx) except ValueError: print('items was already remove') continue self.save_data()
def add_block(self, block): # block is dict here # transactions is a list of transaction object 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) """ update open transaction on peer node, when broadcast block to peer node the some open transactions on peer node should be removed because it will be store in new block """ stored_transactions = self.__open_transactions[:] for itx in block['transactions']: # itx is incoming tx for opentx in stored_transactions: # opentx is open transaction of node # for every incoming transaction, check if it is part of my open transaction if opentx.sender == itx['sender'] and opentx.recipient == itx[ 'recipient'] and opentx.amount == itx[ 'amount'] and opentx.signature == itx['signature']: # if same, try removing it from peer node to prevent encountering second time try: self.__open_transactions.remove(opentx) except ValueError: print('Item was already removed') self.save_data() return True
def mine_block(self): if self.public_key == None: return None hashed_last_block = hash_block(self.get_last_blockchain_value()) proof = self.proof_of_work() block = Block(len(self.__chain), hashed_last_block, self.__date_de_introdus, proof) for rez in block.rezultate: if not Carnet.verify_rezultat(rez): return None self.__chain.append(block) self.__date_de_introdus = [] self.save_data() for node in self.__peer_nodes: url = 'http://{}/broadcast_block'.format(node) block_convertit = block.__dict__.copy() block_convertit['rezultate'] = [ rez.to_ordered_dict() for rez in block_convertit['rezultate'] ] try: response = requests.post(url, json={'block': block_convertit}) if response.status_code == 400 or response.status_code == 500: print('bloc aiurea') if response.status_code == 409: self.resolve_conflicts = True except requests.exceptions.ConnectionError: continue return block
def mine_block(self): last_block = self.__chain[-1] hashed_block = hash_block(last_block) proof = self.proof_of_work() # reward_transaction = { # 'sender': 'MINING', # 'recipient': owner, # 'amount': MINING_REWARD # } reward_transaction = Transaction('MINING', self.hosting_node, MINING_REWARD) # reward_transaction = OrderedDict([('sender', 'MINING'), ('recipient', owner), ('amount', MINING_REWARD)]) # Creating a copy of the open transaction list prevents the reward transaction doesnt # become part of the open transactions, in case we don't reach the code that empties it. # Impoortant to copy by reference instead of value. Otherwise changes in one list affect the other copied_transactions = self.__open_transactions[:] # The last transaction in every block is the mining reward copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) # Below is the code of the block we were using before block started using classes # block = { # 'previous_hash': hashed_block, # 'index': len(blockchain), # 'transactions': copied_transactions, # 'proof': proof # } # We are using double underscore, otherwise we would append to the copy of the chain self.__chain.append(block) self.__open_transactions = [] self.save_data() print('Hashed block: ', hashed_block) print('Blockchain', self.__chain) return True
def proof_of_work(self): last_block = self.__blockchain[-1] last_block_hash = hash_block(last_block) proof = 0 while not Verification.valid_proof(self.__open_transactions, last_block_hash, proof): proof += 1 return proof
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[:] # looping through all the incoming transactions for itx in block['transactions']: for opentx in stored_transactions: # opentx is an object and itx is an dictionary 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 was allready removed') self.save_data() return True
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 incoming_tx in block["transactions"]: for opentx in stored_transactions: if opentx.sender == incoming_tx[ "sender"] and opentx.recipient == incoming_tx[ "recipient"] and opentx.signature == incoming_tx[ "signature"] and opentx.amount == incoming_tx[ "amount"]: try: self.__open_transactions.remove(opentx) except ValueError: print("Item was already removed.") self.save_data() return True
def proof_of_work(self): """Generate a proof of work to commit a new block to the blockchain.""" last_block = self.__chain[-1] last_hash = hash_block(last_block) proof = 0 while not verifier.valid_proof(self.__open_transactions, 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 # verifier = Verification() while not Verification.valid_proof(self.__open_transactions, last_hash, proof): proof += 1 return proof
def verify_chain(cls, blockchain): """ Verify the current blockchain and return True if it's valid, False otherwise.""" for (index, block) in enumerate(blockchain): if index == 0: continue if block.previous_hash != hash_block(blockchain[index - 1]): return False if not cls.valid_proof(block.transactions[:-1], block.previous_hash, block.proof): print('Proof of work is invalid') return False return True
def mine_block(self): """Create a new block and add open transactions to it.""" # Fetch the currently last block of the blockchain print(self.public_key) if self.public_key == None: return None last_block = self.__chain[-1] # Hash the last block (=> to be able to compare it to the stored hash value) hashed_block = hash_block(last_block) proof = self.proof_of_work() # Miners should be rewarded, so let's create a reward transaction # reward_transaction = { # "sender": "MINNER", # "recipient": owner, # "amount": MINING_REWARD # } reward_transaction = Transaction( 'MINING', self.public_key, '', MINING_REWARD) # Copy transaction instead of manipulating the original open_transactions list # This ensures that if for some reason the mining should fail, we don't have the reward transaction stored in the open transactions copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return False copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_transactions = [] self.save_data() for node in self.__peer_nodes: url = 'http://{}/broadcast-block'.format(node) coverted_block = block.__dict__.copy() coverted_block['transactions'] = [ tx.__dict__ for tx in coverted_block['transactions']] try: response = requests.post(url, json={'block': coverted_block}) if response.status_code == 400 and response.status_code == 500: print('Block declined, needs resolving') if response.status_code == 409: self.resolve_conflicts = True except requests.exceptions.ConnectionError: continue return block
def mine_block(self): """Mine the outstanding, pending transactions and commit them to a new block. Add the mining reward as a new pending transaction. """ if self.__public_key is None: return None last_block = self.__chain[-1] hashed_block = hash_block(last_block) proof = self.proof_of_work() reward_transaction = Transaction('MINING', self.__public_key, '', MINING_REWARD) copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return None copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_transactions = [] self.save_data() for node in self.__peer_nodes: url = 'http://{}/broadcast-block'.format(node) converted_block = block.__dict__.copy() converted_block['transactions'] = [tx.__dict__ for tx in block.transactions] try: response = requests.post(url, json={ 'block': converted_block }) if response.status_code == 400 or response.status_code == 500: print('Block declined, needs resolving') if response.status_code == 409: self.resolve_conflicts = True except requests.exceptions.ConnectionError: continue return block