def is_encodable(_type, value): try: base, sub, arrlist = _type except ValueError: base, sub, arrlist = process_type(_type) if arrlist: if not is_list_like(value): return False if arrlist[-1] and len(value) != arrlist[-1][0]: return False sub_type = (base, sub, arrlist[:-1]) return all(is_encodable(sub_type, sub_value) for sub_value in value) elif base == 'address' and is_ens_name(value): # ENS names can be used anywhere an address is needed # Web3.py will resolve the name to an address before encoding it return True elif base == 'bytes' and isinstance(value, str): # Hex-encoded bytes values can be used anywhere a bytes value is needed if is_hex(value) and len(value) % 2 == 0: # Require hex-encoding of full bytes (even length) bytes_val = to_bytes(hexstr=value) return eth_abi_is_encodable(_type, bytes_val) else: return False elif base == 'string' and isinstance(value, bytes): # bytes that were encoded with utf-8 can be used anywhere a string is needed try: string_val = to_text(value) except UnicodeDecodeError: return False else: return eth_abi_is_encodable(_type, string_val) else: return eth_abi_is_encodable(_type, value)
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)
def is_ens_name(value): if not isinstance(value, str): return False elif is_hex_address(value): return False elif is_0x_prefixed(value) and is_hex(value): return False else: return ENS.is_valid_name(value)
def hexstr_if_str(to_type, hexstr_or_primitive): ''' Convert to a type, assuming that strings can be only hexstr (not unicode text) @param to_type is a function that takes the arguments (primitive, hexstr=hexstr, text=text), eg~ to_bytes, to_text, to_hex, to_int, etc @param text_or_primitive in bytes, str, or int. ''' if isinstance(hexstr_or_primitive, str): (primitive, hexstr) = (None, hexstr_or_primitive) if remove_0x_prefix(hexstr) and not is_hex(hexstr): raise ValueError( "when sending a str, it must be a hex string. Got: {0!r}". format(hexstr_or_primitive, )) else: (primitive, hexstr) = (hexstr_or_primitive, None) return to_type(primitive, hexstr=hexstr)
def is_hexstr(value): return is_string(value) and is_hex(value)
def is_hex_encoded_block_hash(value): if not is_string(value): return False return len(remove_0x_prefix(value)) == 64 and is_hex(value)