예제 #1
0
def encode_abi(web3, abi, arguments, data=None):
    argument_types = get_abi_input_types(abi)

    if not check_if_arguments_can_be_encoded(abi, arguments, {}):
        raise TypeError(
            "One or more arguments could not be encoded to the necessary "
            "ABI type.  Expected types are: {0}".format(
                ', '.join(argument_types), ))

    try:
        normalizers = [
            abi_ens_resolver(web3),
            abi_address_to_hex,
            abi_bytes_to_bytes,
            abi_string_to_text,
        ]
        normalized_arguments = map_abi_data(
            normalizers,
            argument_types,
            arguments,
        )
        encoded_arguments = eth_abi_encode_abi(
            argument_types,
            normalized_arguments,
        )
    except EncodingError as e:
        raise TypeError(
            "One or more arguments could not be encoded to the necessary "
            "ABI type: {0}".format(str(e)))

    if data:
        return to_hex(HexBytes(data) + encoded_arguments)
    else:
        return encode_hex(encoded_arguments)
예제 #2
0
def apply_abi_formatters_to_dict(normalizers, abi_dict, data):
    fields = list(set(abi_dict.keys()) & set(data.keys()))
    formatted_values = map_abi_data(
        normalizers,
        [abi_dict[field] for field in fields],
        [data[field] for field in fields],
    )
    formatted_dict = dict(zip(fields, formatted_values))
    return dict(data, **formatted_dict)
예제 #3
0
def abi_request_formatters(normalizers, abis):
    for method, abi_types in abis.items():
        if isinstance(abi_types, list):
            yield method, map_abi_data(normalizers, abi_types)
        elif isinstance(abi_types, dict):
            single_dict_formatter = apply_abi_formatters_to_dict(
                normalizers, abi_types)
            yield method, apply_formatter_at_index(single_dict_formatter, 0)
        else:
            raise TypeError(
                "ABI definitions must be a list or dictionary, got %r" %
                abi_types)
예제 #4
0
    def soliditySha3(cls, abi_types, values):
        """
        Executes sha3 (keccak256) exactly as Solidity does.
        Takes list of abi_types as inputs -- `[uint24, int8[], bool]`
        and list of corresponding values  -- `[20, [-1, 5, 0], True]`
        """
        if len(abi_types) != len(values):
            raise ValueError(
                "Length mismatch between provided abi types and values.  Got "
                "{0} types and {1} values.".format(len(abi_types),
                                                   len(values)))

        if isinstance(cls, type):
            w3 = None
        else:
            w3 = cls
        normalized_values = map_abi_data([abi_ens_resolver(w3)], abi_types,
                                         values)

        hex_string = add_0x_prefix(''.join(
            remove_0x_prefix(hex_encode_abi_type(abi_type, value))
            for abi_type, value in zip(abi_types, normalized_values)))
        return cls.sha3(hexstr=hex_string)
예제 #5
0
def encode_abi(web3, abi, arguments, vmtype, data=None, setabi=None):
    arguments = list(arguments)
    if vmtype == 1:
        inputlength = len(abi['inputs'])
        if inputlength == len(arguments):
            if arguments:
                arrinputs = abi['inputs']
                paramabi = encodeparameters(arrinputs, arguments, setabi)
            else:
                paramabi = []
        else:
            raise Exception(
                'The number of arguments is not matching the methods required number.'
                'You need to pass {} arguments.'.format(inputlength))
        magicnum = ['00', '61', '73', '6d']
        paramabi.insert(0, fnv1_64(bytes(abi['name'], 'utf8')))
        if abi['type'] == 'constructor':
            if data:
                data1 = bytes.fromhex(str(data, encoding='utf8'))
                deploydata = rlp.encode([data1, rlp.encode(paramabi)])
                encodata = ''.join(magicnum) + deploydata.hex()
                return '0x' + encodata
            else:
                return '0x' + rlp.encode(paramabi).hex()
        else:
            encodata = rlp.encode(paramabi).hex()
            return '0x' + encodata

    else:
        argument_types = get_abi_input_types(abi)
        for j in range(len(argument_types)):
            if argument_types[j]:
                if argument_types[j] == 'address':
                    hrpgot, data1 = bech32.decode(arguments[j][:3],
                                                  arguments[j])
                    addr = to_checksum_address(bytes(data1))
                    arguments[j] = addr  # .split(",")
                elif argument_types[j] == 'address[]':
                    for i in range(len(arguments[j])):
                        hrpgot, data1 = bech32.decode(arguments[j][i][:3],
                                                      arguments[j][i])
                        addr = to_checksum_address(bytes(data1))
                        arguments[j][i] = addr

        if not check_if_arguments_can_be_encoded(abi, arguments, {}):
            raise TypeError(
                "One or more arguments could not be encoded to the necessary "
                "ABI type.  Expected types are: {0}".format(
                    ', '.join(argument_types), ))

        try:
            normalizers = [
                abi_ens_resolver(web3),
                abi_address_to_hex,
                abi_bytes_to_bytes,
                abi_string_to_text,
            ]
            normalized_arguments = map_abi_data(
                normalizers,
                argument_types,
                arguments,
            )
            encoded_arguments = eth_abi_encode_abi(
                argument_types,
                normalized_arguments,
            )
        except EncodingError as e:
            raise TypeError(
                "One or more arguments could not be encoded to the necessary "
                "ABI type: {0}".format(str(e)))

        if data:
            return to_hex(HexBytes(data) + encoded_arguments)
        else:
            return encode_hex(encoded_arguments)
예제 #6
0
def test_map_abi_data(types, data, funcs, expected):
    assert map_abi_data(funcs, types, data) == expected