コード例 #1
0
    def __call_by_default(self, args):
        function_abi = find_matching_fn_abi(self._function.contract_abi,
                                            self._function.web3.codec,
                                            fn_identifier=self._function.function_identifier,
                                            args=args)

        return function_abi['constant'] if 'constant' in function_abi.keys() else False
コード例 #2
0
    def _set_function_info(self):
        if not self.abi:
            self.abi = find_matching_fn_abi(self.contract_abi,
                                            self.function_identifier,
                                            self.args, self.kwargs)
        if self.function_identifier is FallbackFn:
            self.selector = encode_hex(b'')
        elif is_text(self.function_identifier):
            self.selector = encode_hex(function_abi_to_4byte_selector(
                self.abi))
        else:
            raise TypeError("Unsupported function identifier")

        self.arguments = merge_args_and_kwargs(self.abi, self.args,
                                               self.kwargs)
コード例 #3
0
 def _find_matching_fn_abi(cls, fn_identifier=None, args=None, kwargs=None):
     return find_matching_fn_abi(cls.abi,
                                 fn_identifier=fn_identifier,
                                 args=args,
                                 kwargs=kwargs)
コード例 #4
0
def call_contract_function(web3,
                           address,
                           normalizers,
                           function_identifier,
                           transaction,
                           block_id=None,
                           contract_abi=None,
                           fn_abi=None,
                           *args,
                           **kwargs):
    """
    Helper function for interacting with a contract function using the
    `eth_call` API.
    """
    call_transaction = prepare_transaction(
        address,
        web3,
        fn_identifier=function_identifier,
        contract_abi=contract_abi,
        fn_abi=fn_abi,
        transaction=transaction,
        fn_args=args,
        fn_kwargs=kwargs,
    )

    if block_id is None:
        return_data = web3.eth.call(call_transaction)
    else:
        return_data = web3.eth.call(call_transaction,
                                    block_identifier=block_id)

    if fn_abi is None:
        fn_abi = find_matching_fn_abi(contract_abi, function_identifier, args,
                                      kwargs)

    output_types = get_abi_output_types(fn_abi)

    try:
        output_data = decode_abi(output_types, return_data)
    except DecodingError as e:
        # Provide a more helpful error message than the one provided by
        # eth-abi-utils
        is_missing_code_error = (return_data in ACCEPTABLE_EMPTY_STRINGS
                                 and web3.eth.getCode(address)
                                 in ACCEPTABLE_EMPTY_STRINGS)
        if is_missing_code_error:
            msg = (
                "Could not transact with/call contract function, is contract "
                "deployed correctly and chain synced?")
        else:
            msg = (
                "Could not decode contract function call {} return data {} for "
                "output_types {}".format(function_identifier, return_data,
                                         output_types))
        raise BadFunctionCallOutput(msg) from e

    _normalizers = itertools.chain(
        BASE_RETURN_NORMALIZERS,
        normalizers,
    )
    normalized_data = map_abi_data(_normalizers, output_types, output_data)

    if len(normalized_data) == 1:
        return normalized_data[0]
    else:
        return normalized_data