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 normalize_address(ens, address): if address: if is_ens_name(address): validate_name_has_address(ens, address) else: validate_address(address) return address
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 == 'bool': return is_boolean(value) elif base == 'uint': if not is_integer(value): return False exp = int(sub) if value < 0 or value >= 2**exp: return False return True elif base == 'int': if not is_integer(value): return False exp = int(sub) if value <= -1 * 2**(exp - 1) or value >= 2**(exp - 1): return False return True elif base == 'string': if not is_string(value): return False return True elif base == 'bytes': if not is_string(value): return False if not sub: return True max_length = int(sub) if isinstance(value, str): decodable = is_hex(value) and len(value) % 2 == 0 return decodable and len(decode_hex(value)) <= max_length elif isinstance(value, bytes): return len(value) <= max_length else: return False elif base == 'address': if is_ens_name(value): return True elif is_address(value): return True else: return False else: raise ValueError("Unsupported type")
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 == 'bool': return is_boolean(value) elif base == 'uint': if not is_integer(value): return False exp = int(sub) if value < 0 or value >= 2**exp: return False return True elif base == 'int': if not is_integer(value): return False exp = int(sub) if value <= -1 * 2**(exp - 1) or value >= 2**(exp - 1): return False return True elif base == 'string': if not is_string(value): return False return True elif base == 'bytes': if not is_string(value): return False if not sub: return True max_length = int(sub) if isinstance(value, str): decodable = is_hex(value) and len(value) % 2 == 0 return decodable and len(decode_hex(value)) <= max_length elif isinstance(value, bytes): return len(value) <= max_length else: False elif base == 'address': if is_ens_name(value): return True elif is_address(value): return True else: return False else: raise ValueError("Unsupported type")
def abi_ens_resolver(w3, abi_type, val): if abi_type == 'address' and is_ens_name(val): if w3 is None: raise InvalidAddress("Could not look up name, because no web3 connection available") elif w3.ens is None: raise InvalidAddress("Could not look up name, because ENS is set to None") else: return (abi_type, validate_name_has_address(w3.ens, val)) else: return (abi_type, val)
def __to_checksum_address(address, web3): if eth_utils.address.is_address(address): if eth_utils.address.is_checksum_address(address): return address else: return eth_utils.address.to_checksum_address(address) elif is_ens_name(address): return __resolve_ens_name_to_address(address, web3=web3) else: raise InvalidAddress("%a is not valid address or ENS name" % address)
def __to_checksum_address(address, web3): if eth_utils.address.is_address(address): if eth_utils.address.is_checksum_address(address): return address else: return eth_utils.address.to_checksum_address(address) elif (re.match("^4[a-zA-Z0-9]+$", address) is not None) and (len(address) == 48): return address elif is_ens_name(address): return __resolve_ens_name_to_address(address, web3=web3) else: raise InvalidAddress("%a is not valid address or ENS name" % address)
def abi_ens_resolver(w3, abi_type, val): if abi_type == 'address' and is_ens_name(val): if w3 is None: raise InvalidAddress("Could not look up name %r because no web3" " connection available" % (val)) elif w3.ens is None: raise InvalidAddress("Could not look up name %r because ENS is" " set to None" % (val)) elif int( w3.net.version) is not 1 and not isinstance(w3.ens, StaticENS): raise InvalidAddress("Could not look up name %r because web3 is" " not connected to mainnet" % (val)) else: return (abi_type, validate_name_has_address(w3.ens, val)) else: return (abi_type, val)
def normalize_property(cls, key, val): if key == 'abi': if isinstance(val, str): val = json.loads(val) validate_abi(val) return val elif key == 'address': if is_ens_name(val): validate_name_has_address(cls.web3.ens, val) return val else: validate_address(val) return to_checksum_address(val) elif key in { 'bytecode_runtime', 'bytecode', }: return HexBytes(val) else: return val