def __getattr__(self, event_name): if '_events' not in self.__dict__: raise NoABIEventsFound( "The abi for this contract contains no event definitions. ", "Are you sure you provided the correct contract abi?") elif event_name not in self.__dict__['_events']: raise MismatchedABI( "The event '{}' was not found in this contract's abi. ".format( event_name), "Are you sure you provided the correct contract abi?") else: return super().__getattribute__(event_name)
def __getattr__(self, function_name): if '_functions' not in self.__dict__: raise NoABIFunctionsFound( "The abi for this contract contains no function definitions. ", "Are you sure you provided the correct contract abi?") elif function_name not in self.__dict__['_functions']: raise MismatchedABI( "The function '{}' was not found in this contract's abi. ". format(function_name), "Are you sure you provided the correct contract abi?") else: return super().__getattribute__(function_name)
def __getattr__(self, function_name): if self.abi is None: raise NoABIFound("There is no ABI found for this contract.", ) elif not self._functions or len(self._functions) == 0: raise NoABIFunctionsFound( "The ABI for this contract contains no function definitions. ", "Are you sure you provided the correct contract ABI?") elif function_name not in self._functions: functions_available = ', '.join( [fn['name'] for fn in self._functions]) raise MismatchedABI( "The function '{}' was not found in this contract's ABI. ". format(function_name), "Here is a list of all of the function names found: ", "{}. ".format(functions_available), "Did you mean to call one of those functions?") else: return super().__getattribute__(function_name)
def get_event_data(abi_codec: ABICodec, event_abi: ABIEvent, log_entry: LogReceipt) -> EventData: """ Given an event ABI and a log entry for that event, return the decoded event data """ if event_abi['anonymous']: log_topics = log_entry['topics'] elif not log_entry['topics']: raise MismatchedABI("Expected non-anonymous event to have 1 or more topics") # type ignored b/c event_abi_to_log_topic(event_abi: Dict[str, Any]) elif event_abi_to_log_topic(event_abi) != log_entry['topics'][0]: # type: ignore raise MismatchedABI("The event signature did not match the provided ABI") else: log_topics = log_entry['topics'][1:] log_topics_abi = get_indexed_event_inputs(event_abi) log_topic_normalized_inputs = normalize_event_input_types(log_topics_abi) log_topic_types = get_event_abi_types_for_decoding(log_topic_normalized_inputs) log_topic_names = get_abi_input_names(ABIEvent({'inputs': log_topics_abi})) if len(log_topics) != len(log_topic_types): raise LogTopicError("Expected {0} log topics. Got {1}".format( len(log_topic_types), len(log_topics), )) log_data = hexstr_if_str(to_bytes, log_entry['data']) log_data_abi = exclude_indexed_event_inputs(event_abi) log_data_normalized_inputs = normalize_event_input_types(log_data_abi) log_data_types = get_event_abi_types_for_decoding(log_data_normalized_inputs) log_data_names = get_abi_input_names(ABIEvent({'inputs': log_data_abi})) # sanity check that there are not name intersections between the topic # names and the data argument names. duplicate_names = set(log_topic_names).intersection(log_data_names) if duplicate_names: raise InvalidEventABI( "The following argument names are duplicated " f"between event inputs: '{', '.join(duplicate_names)}'" ) decoded_log_data = abi_codec.decode_abi(log_data_types, log_data) normalized_log_data = map_abi_data( BASE_RETURN_NORMALIZERS, log_data_types, decoded_log_data ) decoded_topic_data = [ abi_codec.decode_single(topic_type, topic_data) for topic_type, topic_data in zip(log_topic_types, log_topics) ] normalized_topic_data = map_abi_data( BASE_RETURN_NORMALIZERS, log_topic_types, decoded_topic_data ) event_args = dict(itertools.chain( zip(log_topic_names, normalized_topic_data), zip(log_data_names, normalized_log_data), )) event_data = { 'args': event_args, 'event': event_abi['name'], 'logIndex': log_entry['logIndex'], 'transactionIndex': log_entry['transactionIndex'], 'transactionHash': log_entry['transactionHash'], 'address': log_entry['address'], 'blockHash': log_entry['blockHash'], 'blockNumber': log_entry['blockNumber'], } return cast(EventData, AttributeDict.recursive(event_data))