Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
 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)
Ejemplo n.º 4
0
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))