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)