def partial_validation(): values = request.form required = ['root', 'path', 'sender', 'recipient', 'value'] # Check that the required fields are in the POST data if not all(k in values for k in required): return 'Missing values', 400 root = values.get('root') path = json.loads(values.get('path')) transaction = Transaction(values.get('sender'), values.get('recipient'), values.get('value')) if values.get('signature'): transaction.signature = values.get('signature') h = sha256(str(transaction.to_json()).encode()).hexdigest() new_root = blockchain.partialValidation(path, h) result = root == new_root return jsonify(result), 200
def merkle_path(): values = request.form required = ['sender', 'recipient', 'value'] # Check that the required fields are in the POST data if not all(k in values for k in required): return 'Missing values', 400 transaction = Transaction(values.get('sender'), values.get('recipient'), values.get('value')) if values.get('signature'): transaction.signature = values.get('signature') path = blockchain.merkle_path(transaction) if len(path) > 0: root = path[-1] path = path[:-1] return jsonify(path), 200
def new_transaction_signed(): values = request.form required = ['sender', 'recipient_address', 'value', 'signature'] # Check that the required fields are in the POST data if not all(k in values for k in required): return 'Missing values', 400 transaction = Transaction(values['sender'], values['recipient_address'], values['value']) transaction.signature = values['signature'] transaction_result = blockchain.add_new_transaction(transaction) if transaction_result: response = {'message': 'Transaction will be added to Block'} return jsonify(response), 201 else: response = {'message': 'Invalid Transaction!'} return jsonify(response), 406
def search_block_with_transaction(self, transactionHash): '''return block that matches given transaction hash''' fullchain = [json.loads(block) for block in self.chain] for block in fullchain[::-1]: for trans in block['transaction']: trans = json.loads(trans) new_trans = Transaction(trans['sender'], trans['recipient'], trans['value']) if 'signature' in trans.keys(): new_trans.signature = trans['signature'] new_transHash = sha256(str( new_trans.to_json()).encode()).hexdigest() if transactionHash == new_transHash: return block return False
def merkle_path(self, transaction: Transaction): '''return merkle path of given transaction''' path = [] transactionHash = sha256(str( transaction.to_json()).encode()).hexdigest() block = self.search_block_with_transaction(transactionHash) leaves = [] if block: for trans in block['transaction']: trans = json.loads(trans) new_trans = Transaction(trans['sender'], trans['recipient'], trans['value']) if 'signature' in trans.keys(): new_trans.signature = trans['signature'] new_transHash = sha256(str( new_trans.to_json()).encode()).hexdigest() leaves.append(new_transHash) path = self._merklePath(leaves, transactionHash, []) path.append(block['merkle_root']) return path
def valid_chain(self, chain: List[str]) -> bool: '''check if a blockchain (all blocks) is valid''' current_index = 0 chain = json.loads(chain) # load and check every block from the blockchain while current_index < len(chain): block = json.loads(chain[current_index]) current_block = Block(block['index'], block['transaction'], block['timestamp'], block['previous_hash']) current_block.merkle_root = block['merkle_root'] current_block.nonce = block['nonce'] current_block.difficulty = block['difficulty'] # if the current block is NOT the last block if current_index + 1 < len(chain): # if the hash value of the current block != previous block's hash value of the next block, then reject if current_block.compute_hash() != json.loads( chain[current_index + 1])['previous_hash']: return False # check if the current block is an instance from the list of chain if isinstance(current_block.transaction, list): for transaction in current_block.transaction: transaction = json.loads(transaction) # Skip block reward because it does not have signature if transaction['sender'] == 'Block_Reward': continue current_transaction = Transaction(transaction['sender'], transaction['recipient'], transaction['value']) current_transaction.signature = transaction['signature'] # check if digital signature of each transaction is valid, if not then reject if not current_transaction.verify_transaction_signature(): return False # check if hash value of the current block is not valid, if yes then reject if not self.is_valid_proof(current_block, block['hash']): return False current_index += 1 return True