def find_matching_fn_abi(abi, fn_identifier=None, args=None, kwargs=None): args = args or tuple() kwargs = kwargs or dict() num_arguments = len(args) + len(kwargs) if fn_identifier is FallbackFn: return get_fallback_func_abi(abi) if not is_text(fn_identifier): raise TypeError("Unsupported function identifier") name_filter = functools.partial(filter_by_name, fn_identifier) arg_count_filter = functools.partial(filter_by_argument_count, num_arguments) encoding_filter = functools.partial(filter_by_encodability, args, kwargs) function_candidates = pipe(abi, name_filter, arg_count_filter, encoding_filter) if len(function_candidates) == 1: return function_candidates[0] else: matching_identifiers = name_filter(abi) matching_function_signatures = [ abi_to_signature(func) for func in matching_identifiers ] arg_count_matches = len(arg_count_filter(matching_identifiers)) encoding_matches = len(encoding_filter(matching_identifiers)) if arg_count_matches == 0: diagnosis = "\nFunction invocation failed due to improper number of arguments." elif encoding_matches == 0: diagnosis = "\nFunction invocation failed due to no matching argument types." elif encoding_matches > 1: diagnosis = ( "\nAmbiguous argument encoding. " "Provided arguments can be encoded to multiple functions matching this call." ) message = ( "\nCould not identify the intended function with name `{name}`, " "positional argument(s) of type `{arg_types}` and " "keyword argument(s) of type `{kwarg_types}`." "\nFound {num_candidates} function(s) with the name `{name}`: {candidates}" "{diagnosis}").format( name=fn_identifier, arg_types=tuple(map(type, args)), kwarg_types=valmap(type, kwargs), num_candidates=len(matching_identifiers), candidates=matching_function_signatures, diagnosis=diagnosis, ) raise ValidationError(message)
def parse_transaction_input(self, inputdata): selector = inputdata[0:10] argsdata = inputdata[10:] # print(selector) # print(self.func_abi_map_by_selector.keys()) if selector not in self.func_abi_map_by_selector: return None func_abi = self.func_abi_map_by_selector[selector] # print(func_abi) args_abi = get_fn_abi_types_single(func_abi, "inputs") args = decode_single(args_abi, decode_hex(argsdata)) result = dict() result['name'] = func_abi["name"] result['args'] = args result['signature'] = abi_to_signature(func_abi) return result
def parse_abi(self): '''for item in self.contract_abi: if (item["type"] != "constructor"): print(item["name"], " is a ", item["type"]) hash4 = function_signature_to_4byte_selector(item["name"] + '()') print("function hash4:", encode_hex(hash4))''' funclist = filter_by_type("function", self.contract_abi) for func in funclist: signature = abi_to_signature(func) selector = function_signature_to_4byte_selector(signature) # print(func) # print(signature) # print(encode_hex(selector) ) self.func_abi_map_by_selector[encode_hex(selector)] = func self.func_abi_map_by_name[func['name']] = func eventlist = filter_by_type("event", self.contract_abi) for event in eventlist: topic = event_abi_to_log_topic(event) # print(event) # print(encode_hex(topic) ) self.event_abi_map[encode_hex(topic)] = event
def get_func_signature(self, name): if (name not in self.func_abi_map_by_name): return None # abi = self.func_abi_map_by_name[name] return abi_to_signature(name)