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
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)
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)
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