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 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 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) 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('transaction failed') if response.status_code == 409: self.resolve_conflicts = True except requests.exceptions.ConnectionError: continue return block
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 mine_block(self): if self.node is None: return None last_block = self.get_last_entry() hash_value = hash_util.hash_block(last_block) proof = self.proof_of_work(hash_value) mining_transaction = Transaction("MINING", self.node, "", self.MINING_REWARD) self.open_transactions.append(mining_transaction) block = JBlock(len(self.chain), hash_value, self.open_transactions, proof) if self.transaction_signature_is_valid(block): self.__chain.append(block) self.open_transactions = [] FileHandler.save_j_chain(self) for node in self.__peer_nodes: url = "http://{}/broadcast-block".format(node) try: converted_block = block.__dict__.copy() converted_block["transactions"] = [transaction.__dict__ for transaction in converted_block["transactions"]] 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 else: print("Fehler: Die Transactionen wurden geƤndert") return None
def mine_block(self): if self.hosting_node_id is None: return None last_block = self.__chain[-1] hashed_block = hash_util.hash_block(last_block) proof = self.proof_of_work() # Create reward for miners reward_transaction = Transaction('MINING', self.hosting_node_id, '', 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() return block
def mine_block(self): """Create a new block and add open transfers to it.""" if self.hosting_node == None: return None # Fetch the currently last block of the blockchain last_block = self.__chain[-1] print(last_block) # 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 = Transfer(self.hosting_node, "MINING", 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_transfers[:] for tx in copied_transactions: if not Wallet.verify_transfer(tx): return None copied_transactions.append(reward_transaction) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) self.__chain.append(block) self.__open_transfers = [] self.save_data() return block
def mine_block(self): """Create a new block and add open transactions to it.""" # 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) 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[:] 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 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 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 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 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 verify_chain(cls, blockchain): 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('bad proof of work :(') return False return True
def validate_j_chain(cls, chain): for (index, block) in enumerate(chain): if index > 0: if block.previous_hash != hash_util.hash_block( chain[index - 1]): print("Die chain wurde geƤndert") return False if not cls.check_valid_proof(block.transactions[:-1], block.previous_hash, block.proof): print("Proof of work is not valid") return False return True
def verify_chain(cls, blockchain): for (index, block) in enumerate(blockchain): # for genesis block if index == 0: # skipping for genesis block as genesis block doesn't have previous block continue if block.previous_hash != hash_block(blockchain[index - 1]): # checking previous_hash in current block with hashing previous block return False if not cls.valid_proof(block.transactions[:-1], block.previous_hash, block.proof): # checking whether blockchain have proper valid proof or not and -1 is for removing mining block return False return True
def verify_blockchain(cls, blockchain): for (index, block) in enumerate(blockchain): if index == 0: continue if block.prev_hash != hash_block(blockchain[index - 1]): print( "Blockchain may have split. There is a block that is out of order" ) return False if not cls.valid_proof_of_work(block.prev_hash, block.transactions[:-1], block.proof_of_work): print("Proof of work not valid!") return False return True
def mine_block(self): if self.public_key is None: return None last_block = self.__chain[-1] hashed_block = hash_block(last_block) copied_open_transaction = self.__open_transactions[:] print("Failed transaction(s):\n") for tx in copied_open_transaction: if not Wallet.verify_transaction(tx): print(tx) print('\n') copied_open_transaction.remove(tx) proof = self.proof_of_work(copied_open_transaction) reward_transaction = Transaction('MINING', self.public_key, '', Mining_reward) copied_open_transaction.append(reward_transaction) block = Block(len(self.__chain), hashed_block, proof, copied_open_transaction) self.__chain.append(block) self.__open_transactions.clear() self.save_data() for node in self.__peer_node: url = 'http://{}/broadcast-block'.format(node) converted_block = block.__dict__.copy() converted_block[transactions_str] = [ tx.__dict__ for tx in converted_block[transactions_str] ] try: response = requests.post(url, json={'block': converted_block}) print(response.status_code) if response.status_code == 400 or response.status_code == 500: print('Block declined needs resolving') if response.status_code == 409: self.resolve_conflict = True except requests.exceptions.ConnectionError: continue return block
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 mine_block(self): """ Mines a new block """ # make sure we cant mine without valid wallet if self.public_key is None: # return False For Old Node.py return None last_block = self.__chain[-1] # shows current last block of blockchain hashed_block = hash_block(last_block) proof = self.proof_of_work() # reward_transaction = { # 'sender': 'MINING', # 'recipient': owner, # 'amount': MINING_REWARD # } # using ordered dictionary instead 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 # return False For Old Node.py copied_transactions = self.__open_transactions[:] for tx in copied_transactions: if not Wallet.verify_transaction(tx): return None copied_transactions.append(reward_transaction) # for key in last_block: # for loop on dictionary only loops over keys # value = last_block[key] # hashed_block = hashed_block + str(value) # print(hashed_block) block = Block(len(self.__chain), hashed_block, copied_transactions, proof) # block = { # 'previous_hash': hashed_block, # 'index': len(blockchain), # 'transactions': copied_transactions, # 'proof': proof # } # dictionary / we add stringyfied versino here. 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