示例#1
0
def test_hexstr_if_str_on_invalid_hex(val):
    try:
        is_hexstr = (is_hex(val) or val == '')
    except ValueError:
        is_hexstr = False

    if not is_hexstr:
        with pytest.raises(ValueError):
            hexstr_if_str(Mock(), val)
示例#2
0
def abi_int_to_hex(
        abi_type: BasicType, type_str: TypeStr, data: Any
) -> Optional[Tuple[TypeStr, HexStr]]:
    if abi_type.base == 'uint' and not abi_type.is_array:
        # double check?
        return type_str, hexstr_if_str(to_hex, data)
    return None
示例#3
0
def decode_event_data(data: str, event_abi: Dict[str, Any]) -> Tuple:
    """Decode the data of an event according to the event's abi entry"""
    log_data = hexstr_if_str(to_bytes, data)
    log_data_abi = exclude_indexed_event_inputs(event_abi)  # type: ignore
    log_data_normalized_inputs = normalize_event_input_types(log_data_abi)
    log_data_types = get_event_abi_types_for_decoding(log_data_normalized_inputs)
    decoded_log_data = ABI_CODEC.decode_abi(log_data_types, log_data)
    return decoded_log_data
示例#4
0
def abi_bytes_to_hex(abi_type, type_str, data):
    if abi_type.base != 'bytes' or abi_type.is_array:
        return

    bytes_data = hexstr_if_str(to_bytes, data)
    if abi_type.sub is None:
        return type_str, to_hex(bytes_data)

    num_bytes = abi_type.sub
    if len(bytes_data) > num_bytes:
        raise ValueError(
            "This value was expected to be at most %d bytes, but instead was %d: %r"
            % ((num_bytes, len(bytes_data), data)))

    padded = bytes_data.ljust(num_bytes, b'\0')
    return type_str, to_hex(padded)
示例#5
0
def abi_bytes_to_hex(abi_type: BasicType, type_str: TypeStr,
                     data: Any) -> Optional[Tuple[TypeStr, HexStr]]:
    if abi_type.base != 'bytes' or abi_type.is_array:
        return None

    bytes_data = hexstr_if_str(to_bytes, data)
    if abi_type.sub is None:
        return type_str, to_hex(bytes_data)

    num_bytes = abi_type.sub
    if len(bytes_data) > num_bytes:
        raise ValueError(
            f"This value was expected to be at most {num_bytes} bytes, "
            f"but instead was {len(bytes_data)}: {data!r}")

    padded = bytes_data.ljust(num_bytes, b'\0')
    return type_str, to_hex(padded)
示例#6
0
def abi_bytes_to_hex(abi_type, data):
    base, sub, arrlist = process_type(abi_type)
    if base == 'bytes' and not arrlist:
        bytes_data = hexstr_if_str(to_bytes, data)
        if not sub:
            return abi_type, to_hex(bytes_data)
        else:
            num_bytes = int(sub)
            if len(bytes_data) <= num_bytes:
                padded = bytes_data.ljust(num_bytes, b'\0')
                return abi_type, to_hex(padded)
            else:
                raise ValueError(
                    "This value was expected to be at most %d bytes, but instead was %d: %r" % (
                        (num_bytes, len(bytes_data), data)
                    )
                )
示例#7
0
def abi_bytes_to_bytes(abi_type, type_str, data):
    if abi_type.base == 'bytes' and not abi_type.is_array:
        return type_str, hexstr_if_str(to_bytes, data)
示例#8
0
def abi_int_to_hex(abi_type, type_str, data):
    if abi_type.base == 'uint' and not abi_type.is_array:
        return abi_type, hexstr_if_str(to_hex, data)
示例#9
0
def test_hexstr_if_str_on_valid_hex(val):
    to_type = Mock(return_value='zoot')
    assert hexstr_if_str(to_type, val) == 'zoot'
    assert to_type.call_args == ((None, ), {'hexstr': val})
示例#10
0
def test_hexstr_if_str_curried():
    converter = hexstr_if_str(to_hex)
    assert converter(255) == '0xff'
示例#11
0
def test_hexstr_if_str_passthrough(val):
    to_type = Mock(return_value='zoot')
    assert hexstr_if_str(to_type, val) == 'zoot'
    assert to_type.call_args == ((val, ), {'hexstr': None})
示例#12
0
def abi_int_to_hex(abi_type, data):
    base, _sub, arrlist = process_type(abi_type)
    if base == 'uint' and not arrlist:
        return abi_type, hexstr_if_str(to_hex, data)
示例#13
0
def get_event_data(event_abi, log_entry):
    """
    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")
    elif event_abi_to_log_topic(event_abi) != log_entry['topics'][0]:
        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({'inputs': log_topics_abi})

    if len(log_topics) != len(log_topic_types):
        raise ValueError("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({'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 ValueError(
            "Invalid Event ABI:  The following argument names are duplicated "
            "between event inputs: '{0}'".format(', '.join(duplicate_names))
        )

    decoded_log_data = 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 = [
        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 AttributeDict.recursive(event_data)
示例#14
0
def abi_bytes_to_bytes(abi_type: BasicType, type_str: TypeStr,
                       data: Any) -> Optional[Tuple[TypeStr, HexStr]]:
    if abi_type.base == 'bytes' and not abi_type.is_array:
        return type_str, hexstr_if_str(to_bytes, data)
    return None
示例#15
0
def abi_bytes_to_bytes(abi_type, data):
    base, sub, arrlist = process_type(abi_type)
    if base == 'bytes' and not arrlist:
        return abi_type, hexstr_if_str(to_bytes, data)
示例#16
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))
示例#17
0
 )),
 RPC.eth_estimateGas:
 apply_one_of_formatters((
     (is_length(1), estimate_gas_without_block_id),
     (is_length(2), estimate_gas_with_block_id),
 )),
 RPC.eth_sendTransaction:
 apply_formatter_at_index(transaction_param_formatter, 0),
 RPC.eth_signTransaction:
 apply_formatter_at_index(transaction_param_formatter, 0),
 RPC.eth_getProof:
 apply_formatter_at_index(to_hex_if_integer, 2),
 # personal
 RPC.personal_importRawKey:
 apply_formatter_at_index(
     compose(remove_0x_prefix, hexstr_if_str(to_hex)),
     0,
 ),
 RPC.personal_sign:
 apply_formatter_at_index(text_if_str(to_hex), 0),
 RPC.personal_ecRecover:
 apply_formatter_at_index(text_if_str(to_hex), 0),
 RPC.personal_sendTransaction:
 apply_formatter_at_index(transaction_param_formatter, 0),
 # Snapshot and Revert
 RPC.evm_revert:
 apply_formatter_at_index(integer_to_hex, 0),
 RPC.trace_replayBlockTransactions:
 apply_formatter_at_index(to_hex_if_integer, 0),
 RPC.trace_block:
 apply_formatter_at_index(to_hex_if_integer, 0),
示例#18
0
     ),
     'eth_getUncleByBlockHashAndIndex': apply_formatter_at_index(integer_to_hex, 1),
     'eth_newFilter': apply_formatter_at_index(filter_params_formatter, 0),
     'eth_getLogs': apply_formatter_at_index(filter_params_formatter, 0),
     'eth_call': combine_argument_formatters(
         transaction_param_formatter,
         block_number_formatter,
     ),
     'eth_estimateGas': apply_one_of_formatters((
         (estimate_gas_without_block_id, is_length(1)),
         (estimate_gas_with_block_id, is_length(2)),
     )),
     'eth_sendTransaction': apply_formatter_at_index(transaction_param_formatter, 0),
     # personal
     'personal_importRawKey': apply_formatter_at_index(
         compose(remove_0x_prefix, hexstr_if_str(to_hex)),
         0,
     ),
     'personal_sign': apply_formatter_at_index(text_if_str(to_hex), 0),
     'personal_ecRecover': apply_formatter_at_index(text_if_str(to_hex), 0),
     'personal_sendTransaction': apply_formatter_at_index(transaction_param_formatter, 0),
     # Snapshot and Revert
     'evm_revert': apply_formatter_at_index(integer_to_hex, 0),
     'trace_replayBlockTransactions': apply_formatter_at_index(block_number_formatter, 0),
     'trace_block': apply_formatter_at_index(block_number_formatter, 0),
     'trace_call': compose(
         apply_formatter_at_index(transaction_param_formatter, 0),
         apply_formatter_at_index(block_number_formatter, 2)
     ),
 },
 result_formatters={