def call_contract_function(contract, function_name, transaction, *args, **kwargs): """ Helper function for interacting with a contract function using the `eth_call` API. """ call_transaction = contract._prepare_transaction( fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) return_data = contract.web3.eth.call(call_transaction) function_abi = contract._find_matching_fn_abi(function_name, args, kwargs) output_types = get_abi_output_types(function_abi) output_data = decode_abi(output_types, return_data) normalized_data = [ normalize_return_type(data_type, data_value) for data_type, data_value in zip(output_types, output_data) ] if len(normalized_data) == 1: return normalized_data[0] else: return normalized_data
def call_contract_function(contract, function_name, transaction, *args, **kwargs): """ Helper function for interacting with a contract function using the `eth_call` API. """ call_transaction = contract._prepare_transaction( fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) return_data = contract.web3.eth.call(call_transaction) function_abi = contract._find_matching_fn_abi(function_name, args, kwargs) output_types = get_abi_output_types(function_abi) output_data = decode_abi(output_types, return_data) normalized_data = [ normalize_return_type(data_type, data_value) for data_type, data_value in zip(output_types, output_data) ] if len(normalized_data) == 1: return normalized_data[0] else: return normalized_data
def call_contract_function(contract, function_name, transaction, *args, **kwargs): """ Helper function for interacting with a contract function using the `eth_call` API. """ call_transaction = contract._prepare_transaction( fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) return_data = contract.web3.eth.call(call_transaction) function_abi = contract._find_matching_fn_abi(function_name, args, kwargs) output_types = get_abi_output_types(function_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 contract.web3.eth.getCode(contract.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_name, return_data, output_types)) raise_from(BadFunctionCallOutput(msg), e) normalized_data = [ normalize_return_type(data_type, data_value) for data_type, data_value in zip(output_types, output_data) ] if len(normalized_data) == 1: return normalized_data[0] else: return normalized_data
def call_contract_function(contract, function_name, transaction, *args, **kwargs): """ Helper function for interacting with a contract function using the `eth_call` API. """ call_transaction = contract._prepare_transaction( fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) return_data = contract.web3.eth.call(call_transaction) function_abi = contract._find_matching_fn_abi(function_name, args, kwargs) output_types = get_abi_output_types(function_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 msg = ( "Could not decode contract function call {} return data {} for " "output_types {}".format( function_name, return_data, output_types ) ) raise_from(BadFunctionCallOutput(msg), e) normalized_data = [ normalize_return_type(data_type, data_value) for data_type, data_value in zip(output_types, output_data) ] if len(normalized_data) == 1: return normalized_data[0] else: return normalized_data
def call_contract_function(contract, function_name, transaction, *args, **kwargs): """ Helper function for interacting with a contract function using the `eth_call` API. """ call_transaction = contract._prepare_transaction( fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) return_data = contract.web3.eth.call(call_transaction) function_abi = contract._find_matching_fn_abi(function_name, args, kwargs) output_types = get_abi_output_types(function_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 msg = ( "Could not decode contract function call {} return data {} for " "output_types {}".format( function_name, return_data, output_types ) ) raise_from(BadFunctionCallOutput(msg), e) normalized_data = [ normalize_return_type(data_type, data_value) for data_type, data_value in zip(output_types, output_data) ] if len(normalized_data) == 1: return normalized_data[0] else: return normalized_data
def call_contract_function(contract, function_name, transaction, *args, **kwargs): """Calls a contract constant or function. The function must not have state changing effects. For those see :func:`transact_with_contract_function` For usual cases, you do not want to call this directly, but interact with your contract through :meth:`Contract.call` method. :param contract: :class:`web3.contract.Contract` object instance :param function_name: Contract function name to call :param transaction: Transaction parameters to pass to underlying ``web3.eth.call`` :param *arguments: Arguments to be passed to contract function. Automatically encoded :return: Function call results, encoded to Python object """ if transaction is None: call_transaction = {} else: call_transaction = dict(**transaction) function_abi = contract.find_matching_fn_abi(function_name, args, kwargs) function_selector = function_abi_to_4byte_selector(function_abi) arguments = merge_args_and_kwargs(function_abi, args, kwargs) call_transaction['data'] = contract.encodeABI( function_name, arguments, data=function_selector, ) return_data = contract.web3.eth.call(call_transaction) output_types = get_abi_output_types(function_abi) output_data = decode_abi(output_types, return_data) normalized_data = [ normalize_return_type(data_type, data_value) for data_type, data_value in zip(output_types, output_data) ] if len(normalized_data) == 1: return normalized_data[0] else: return normalized_data
def test_normalizing_return_values(data_type, data_value, expected_value): actual_value = normalize_return_type(data_type, data_value) assert actual_value == expected_value