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)
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)
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)
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)
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)
def test_map_abi_data(types, data, funcs, expected): assert map_abi_data(funcs, types, data) == expected