Exemple #1
0
 def __repr__(self):
     if self.abi:
         _repr = '<Function %s' % abi_to_signature(self.abi)
         if self.arguments is not None:
             _repr += ' bound to %r' % (self.arguments, )
         return _repr + '>'
     return '<Function %s>' % self.fn_name
Exemple #2
0
 def __repr__(self):
     if self.abi:
         _repr = '<Function %s' % abi_to_signature(self.abi)
         if self.arguments is not None:
             _repr += ' bound to %r' % (self.arguments,)
         return _repr + '>'
     return '<Function %s>' % self.fn_name
def find_matching_fn_abi(abi,
                         abi_codec,
                         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, abi_codec,
                                        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)
Exemple #4
0
def find_matching_fn_abi(
    abi: ABI,
    abi_codec: ABICodec,
    fn_identifier: Optional[Union[str, Type[FallbackFn],
                                  Type[ReceiveFn]]] = None,
    args: Optional[Sequence[Any]] = None,
    kwargs: Optional[Any] = None,
) -> ABIFunction:
    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 fn_identifier is ReceiveFn:
        return get_receive_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, abi_codec,
                                        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 = (
            f"\nCould not identify the intended function with name `{fn_identifier}`, positional "
            f"argument(s) of type `{tuple(map(type, args))}` and keyword argument(s) of type "
            f"`{valmap(type, kwargs)}`.\nFound {len(matching_identifiers)} function(s) with "
            f"the name `{fn_identifier}`: {matching_function_signatures}{diagnosis}"
        )

        raise ValidationError(message)
Exemple #5
0
def contract_method_ID(methodname, abi):
    """
    build the 4 byte ID, from abi & methodname
    """
    method_abi = filter_by_name(methodname, abi)
    assert (len(method_abi) == 1)
    method_abi = method_abi[0]
    method_signature = abi_to_signature(method_abi)
    method_signature_hash_bytes = w3.sha3(text=method_signature)
    method_signature_hash_hex = w3.toHex(method_signature_hash_bytes)
    method_signature_hash_4bytes = method_signature_hash_hex[0:10]
    return method_signature_hash_4bytes
Exemple #6
0
def find_matching_fn_abi(abi, fn_identifier=None, args=None, kwargs=None):
    args = args or tuple()
    kwargs = kwargs or dict()
    filters = []
    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)
    filters.extend([
        name_filter,
        arg_count_filter,
        encoding_filter,
    ])
    function_candidates = pipe(abi, *filters)
    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 get_event_list_by_protocol(protocol):
    events = {}
    for contract_name in os.listdir(f'../abi/{protocol}'):
        file_path = f'../abi/{protocol}/{contract_name}'
        abi = get_abi(file_path)['abi']
        events_abi = filter_by_type('event', abi)
        for event_abi in events_abi:
            events.update({
                to_hex(event_abi_to_log_topic(event_abi)): {
                    'name': event_abi['name'],
                    'inputs': event_abi['inputs'],
                    'anonymous': event_abi['anonymous'],
                    'signature': abi_to_signature(event_abi),
                    'abi': event_abi
                }
            })
    return events
Exemple #8
0
def validate_contract_existence(contract: Contract) -> None:
    """Verifies if a given contract exists on the chain.

    It checks if any code is stored for the address. For events and functions
    in the ABI it will be checked if their signature hash can be found within
    the code. Throws an exception if the contract could not be verified. Else
    return nothing.
    """

    contract_code = contract.web3.eth.getCode(contract.address)

    if not contract_code:
        raise ValueError(
            f"The given contract address {to_checksum_address(contract.address)} "
            f"does not point to a contract!"
        )

    for description in contract.abi:
        description_type = description.get("type", "function")

        if description_type in ("constructor", "fallback"):
            continue

        assert description_type in ("function", "event")

        signature = abi_to_signature(description)
        signature_hash = Web3.keccak(text=signature)

        if description_type == "function":
            description_exists_in_code = signature_hash[:4] in contract_code

        else:
            description_exists_in_code = signature_hash in contract_code

        if not description_exists_in_code:
            raise ValueError(
                f"The contract at the given address {to_checksum_address(contract.address)} does "
                f"not support the {description_type} with the following signature: {signature}!"
            )
Exemple #9
0
 def callable_check(fn_abi):
     return abi_to_signature(fn_abi) == signature
Exemple #10
0
 def callable_check(fn_abi):
     return abi_to_signature(fn_abi) == signature