def decode_contract_call(contract_abi: list, call_data: str): call_data_bin = decode_hex(call_data) method_signature = call_data_bin[:4] for description in contract_abi: if description.get('type') != 'function': continue method_name = normalize_abi_method_name(description['name']) arg_types = [item['type'] for item in description['inputs']] method_id = get_abi_method_id(method_name, arg_types) if zpad(encode_int(method_id), 4) == method_signature: args = decode_abi(arg_types, call_data_bin[4:]) return method_name, args
def decode_contract_call(contract_abi, call_data): call_data = call_data.lower().replace("0x", "") call_data_bin = decode_hex(call_data) method_signature = call_data_bin[:4] for description in contract_abi: if description.get('type') != 'function': continue method_name = normalize_abi_method_name(description['name']) arg_types = [item['type'] for item in description['inputs']] method_id = get_abi_method_id(method_name, arg_types) if zpad(encode_int(method_id), 4) == method_signature: try: # TODO: ethereum.abi.decode_abi vs eth_abi.decode_abi args = decode_abi(arg_types, call_data_bin[4:]) except AssertionError: # Invalid args continue return method_name, args
def decode_contract_call(self, contract_abi: list, TID: str): Transaction = self.w3.eth.getTransaction(TID) call_data = str(Transaction.input) call_data_bin = decode_hex(call_data) method_signature = call_data_bin[:4] for description in contract_abi: if description.get('type') != 'function': continue method_name = normalize_abi_method_name(description['name']) arg_types = [item['type'] for item in description['inputs']] method_id = get_abi_method_id(method_name, arg_types) if zpad(encode_int(method_id), 4) == method_signature: try: args = decode_abi(arg_types, call_data_bin[4:]) except AssertionError: # Invalid args continue return method_name, args
def _decode_input(contract_abi, call_data): """ Decode input data of a transaction according to a contract ABI Solution from https://ethereum.stackexchange.com/questions/20897/how-to-decode-input-data-from-tx-using-python3?rq=1 Parameters ---------- contract_abi : list List of contract methods specifications call_data : str Input of transaction in a form of 0x(4 bytes of method)(arguments), i.e. 0x12345678000000000000.... Returns ------- dict Name and parsed parameters extracted from the input None, if there is no such method in ABI, or there was a problem with method arguments """ call_data_bin = decode_hex(call_data) method_signature = call_data_bin[:4] for description in contract_abi: if description.get('type') not in ['function', 'event']: continue method_name = normalize_abi_method_name(description['name']) arg_types = [item['type'] for item in description['inputs']] method_id = get_abi_method_id(method_name, arg_types) if zpad(encode_int(method_id), 4) == method_signature: try: args = decode_abi(arg_types, call_data_bin[4:]) args = [{'type': arg_types[index], 'value': str(value)} for index, value in enumerate(args)] except AssertionError: continue return { 'name': method_name, 'params.type': [arg["type"] for arg in args], 'params.value': [arg["value"] for arg in args] }