def map_abi_data(normalizers, types, data): ''' This function will apply normalizers to your data, in the context of the relevant types. Each normalizer is in the format: def normalizer(datatype, data): # Conditionally modify data return (datatype, data) Where datatype is a valid ABI type string, like "uint". In case of an array, like "bool[2]", normalizer will receive `data` as an iterable of typed data, like `[("bool", True), ("bool", False)]`. Internals --- This is accomplished by: 1. Decorating the data tree with types 2. Recursively mapping each of the normalizers to the data 3. Stripping the types back out of the tree ''' pipeline = itertools.chain( [abi_data_tree(types)], map(data_tree_map, normalizers), [partial(recursive_map, strip_abi_type)], ) return pipe(data, *pipeline)
def factory(cls, web3, class_name=None, **kwargs): kwargs['web3'] = web3 normalizers = { 'abi': normalize_abi, 'address': partial(normalize_address, kwargs['web3'].ens), 'bytecode': normalize_bytecode, 'bytecode_runtime': normalize_bytecode, } contract = PropertyCheckingFactory( class_name or cls.__name__, (cls,), kwargs, normalizers=normalizers) setattr(contract, 'functions', ContractFunctions(contract.abi, contract.web3)) setattr(contract, 'events', ContractEvents(contract.abi, contract.web3)) setattr(contract, 'fallback', Contract.get_fallback_function(contract.abi, contract.web3)) return contract
valmap, ) from .formatting import ( construct_formatting_middleware, ) def bytes_to_ascii(value): return codecs.decode(value, 'ascii') to_ascii_if_bytes = apply_formatter_if(is_bytes, bytes_to_ascii) to_integer_if_hex = apply_formatter_if(is_string, hex_to_integer) block_number_formatter = apply_formatter_if(is_integer, integer_to_hex) is_false = partial(operator.is_, False) is_not_false = complement(is_false) is_not_null = complement(is_null) @curry def to_hexbytes(num_bytes, val, variable_length=False): if isinstance(val, (str, int, bytes)): result = HexBytes(val) else: raise TypeError("Cannot convert %r to HexBytes" % val) extra_bytes = len(result) - num_bytes if extra_bytes == 0 or (variable_length and extra_bytes < 0): return result
} filter_params_remapper = apply_key_map(FILTER_PARAMS_MAPPINGS) FILTER_PARAMS_FORMATTERS = { 'fromBlock': to_integer_if_hex, 'toBlock': to_integer_if_hex, } filter_params_formatter = apply_formatters_to_dict(FILTER_PARAMS_FORMATTERS) filter_params_transformer = compose(filter_params_remapper, filter_params_formatter) TRANSACTION_FORMATTERS = { 'to': apply_formatter_if(partial(operator.eq, ''), static_return(None)), } transaction_formatter = apply_formatters_to_dict(TRANSACTION_FORMATTERS) RECEIPT_FORMATTERS = { 'logs': apply_formatter_to_array(log_key_remapper), } receipt_formatter = apply_formatters_to_dict(RECEIPT_FORMATTERS) transaction_params_transformer = compose(transaction_params_remapper, transaction_params_formatter)
import pytest from web3.utils.blocks import ( select_method_for_block_identifier, ) from web3.utils.toolz import ( partial, ) selector_fn = partial( select_method_for_block_identifier, if_hash='test_hash', if_number='test_number', if_predefined='test_predefined', ) @pytest.mark.parametrize( 'input,expected', ( ('latest', 'test_predefined'), ('pending', 'test_predefined'), ('earliest', 'test_predefined'), (-1, ValueError), (0, 'test_number'), (1, 'test_number'), (4000000, 'test_number'), ('0x0', 'test_number'), ('0x00', 'test_number'), ('0x1', 'test_number'), ('0x01', 'test_number'), (hex(4000000), 'test_number'), ('0x' + ''.zfill(64), 'test_hash'),