diff --git a/docs/ens_overview.rst b/docs/ens_overview.rst index 1b74958f20..89ae116f16 100644 --- a/docs/ens_overview.rst +++ b/docs/ens_overview.rst @@ -61,9 +61,8 @@ Look up the address for an ENS name assert eth_address == '0x5B2063246F2191f18F2675ceDB8b28102e957458' - # ens.py will assume you want a .eth name if you don't specify a full name - - assert ns.address('jasoncarver') == eth_address +The ``ENS`` module has no opinion as to which TLD you can use, +but will not infer a TLD if it is not provided with the name. Get name from address diff --git a/ens/constants.py b/ens/constants.py index 2f0971a362..8ee310bc28 100644 --- a/ens/constants.py +++ b/ens/constants.py @@ -9,6 +9,4 @@ MIN_ETH_LABEL_LENGTH = 7 -RECOGNIZED_TLDS = ['eth', 'reverse', 'test', 'luxe', 'xyz'] - REVERSE_REGISTRAR_DOMAIN = 'addr.reverse' diff --git a/ens/main.py b/ens/main.py index 1dd4812a16..7aafc12516 100644 --- a/ens/main.py +++ b/ens/main.py @@ -20,13 +20,12 @@ address_to_reverse_domain, default, dict_copy, - dot_eth_name, - dot_eth_namehash, init_web3, is_valid_name, label_to_hash, - name_to_hash, + normal_name_to_hash, normalize_name, + raw_name_to_hash, ) ENS_MAINNET_ADDR = '0x314159265dD8dbb310642f98f50C066173C1259b' @@ -43,7 +42,7 @@ class ENS: ''' labelhash = staticmethod(label_to_hash) - namehash = staticmethod(dot_eth_namehash) + namehash = staticmethod(raw_name_to_hash) nameprep = staticmethod(normalize_name) is_valid_name = staticmethod(is_valid_name) reverse_domain = staticmethod(address_to_reverse_domain) @@ -72,19 +71,14 @@ def fromWeb3(cls, web3, addr=None): ''' return cls(web3.manager.provider, addr=addr) - def address(self, name, guess_tld=True): + def address(self, name): ''' Look up the Ethereum address that `name` currently points to. :param str name: an ENS name to look up - :param bool guess_tld: should `name` be appended with '.eth' if no common TLD found? :raises InvalidName: if `name` has invalid syntax ''' - if guess_tld: - expanded = dot_eth_name(name) - else: - expanded = name - return self.resolve(expanded, 'addr') + return self.resolve(name, 'addr') def name(self, address): ''' @@ -109,9 +103,9 @@ def setup_address(self, name, address=default, transact={}): and calls this method with ``sub.parentname.eth``, then ``sub`` will be created as part of this call. - :param str name: ENS name to set up, in checksum format - :param str address: name will point to this address. If ``None``, erase the record. - If not specified, name will point to the owner's address. + :param str name: ENS name to set up + :param str address: name will point to this address, in checksum format. If ``None``, + erase the record. If not specified, name will point to the owner's address. :param dict transact: the transaction configuration, like in :meth:`~web3.eth.Eth.sendTransaction` :raises InvalidName: if ``name`` has invalid syntax @@ -133,7 +127,7 @@ def setup_address(self, name, address=default, transact={}): address = EMPTY_ADDR_HEX transact['from'] = owner resolver = self._set_resolver(name, transact=transact) - return resolver.setAddr(dot_eth_namehash(name), address, transact=transact) + return resolver.setAddr(raw_name_to_hash(name), address, transact=transact) @dict_copy def setup_name(self, name, address=None, transact={}): @@ -183,13 +177,13 @@ def resolve(self, name, get='addr'): resolver = self.resolver(normal_name) if resolver: lookup_function = getattr(resolver, get) - namehash = name_to_hash(normal_name) + namehash = normal_name_to_hash(normal_name) return lookup_function(namehash) else: return None def resolver(self, normal_name): - resolver_addr = self.ens.resolver(name_to_hash(normal_name)) + resolver_addr = self.ens.resolver(normal_name_to_hash(normal_name)) if not resolver_addr: return None return self._resolverContract(address=resolver_addr) @@ -209,7 +203,7 @@ def owner(self, name): :return: owner address :rtype: str ''' - node = dot_eth_namehash(name) + node = raw_name_to_hash(name) return self.ens.owner(node) @dict_copy @@ -270,7 +264,7 @@ def _first_owner(self, name): ''' owner = None unowned = [] - pieces = dot_eth_name(name).split('.') + pieces = normalize_name(name).split('.') while pieces and not owner: name = '.'.join(pieces) owner = self.owner(name) @@ -283,7 +277,7 @@ def _claim_ownership(self, owner, unowned, owned, old_owner=None, transact={}): transact['from'] = old_owner or owner for label in reversed(unowned): self.ens.setSubnodeOwner( - dot_eth_namehash(owned), + raw_name_to_hash(owned), label_to_hash(label), owner, transact=transact @@ -294,7 +288,7 @@ def _claim_ownership(self, owner, unowned, owned, old_owner=None, transact={}): def _set_resolver(self, name, resolver_addr=None, transact={}): if not resolver_addr: resolver_addr = self.address('resolver.eth') - namehash = dot_eth_namehash(name) + namehash = raw_name_to_hash(name) if self.ens.resolver(namehash) != resolver_addr: self.ens.setResolver( namehash, @@ -306,12 +300,12 @@ def _set_resolver(self, name, resolver_addr=None, transact={}): @dict_copy def _setup_reverse(self, name, address, transact={}): if name: - name = dot_eth_name(name) + name = normalize_name(name) else: name = '' transact['from'] = address return self._reverse_registrar().setName(name, transact=transact) def _reverse_registrar(self): - addr = self.ens.owner(name_to_hash(REVERSE_REGISTRAR_DOMAIN)) + addr = self.ens.owner(normal_name_to_hash(REVERSE_REGISTRAR_DOMAIN)) return self.web3.eth.contract(address=addr, abi=abis.REVERSE_REGISTRAR) diff --git a/ens/utils.py b/ens/utils.py index ccb6b077ad..5c269ccc8c 100644 --- a/ens/utils.py +++ b/ens/utils.py @@ -1,4 +1,3 @@ - import copy import datetime import functools @@ -16,7 +15,6 @@ AUCTION_START_GAS_MARGINAL, EMPTY_SHA3_BYTES, MIN_ETH_LABEL_LENGTH, - RECOGNIZED_TLDS, REVERSE_REGISTRAR_DOMAIN, ) from ens.exceptions import ( @@ -108,18 +106,6 @@ def is_valid_name(name): return False -def label_to_name(label, default_tld, recognized_tlds): - label = normalize_name(label) - pieces = label.split('.') - if pieces[-1] not in recognized_tlds: - pieces.append(default_tld) - return '.'.join(pieces) - - -def dot_eth_name(label): - return label_to_name(label, 'eth', RECOGNIZED_TLDS) - - def name_to_label(name, registrar): name = normalize_name(name) if '.' not in name: @@ -171,7 +157,7 @@ def label_to_hash(label): return Web3().keccak(text=label) -def name_to_hash(name): +def normal_name_to_hash(name): node = EMPTY_SHA3_BYTES if name: labels = name.split(".") @@ -183,15 +169,14 @@ def name_to_hash(name): return node -def dot_eth_namehash(name): +def raw_name_to_hash(name): ''' Generate the namehash. This is also known as the ``node`` in ENS contracts. In normal operation, generating the namehash is handled behind the scenes. For advanced usage, it is a helpful utility. - This will add '.eth' to name if no TLD given. Also, it normalizes the name with - `nameprep + This normalizes the name with `nameprep `_ before hashing. @@ -200,8 +185,8 @@ def dot_eth_namehash(name): :rtype: bytes :raises InvalidName: if ``name`` has invalid syntax ''' - expanded_name = dot_eth_name(name) - return name_to_hash(expanded_name) + normalized_name = normalize_name(name) + return normal_name_to_hash(normalized_name) def address_in(address, addresses): diff --git a/tests/.DS_Store b/tests/.DS_Store new file mode 100644 index 0000000000..93c2bfb7e7 Binary files /dev/null and b/tests/.DS_Store differ diff --git a/tests/core/.DS_Store b/tests/core/.DS_Store new file mode 100644 index 0000000000..c70013ac86 Binary files /dev/null and b/tests/core/.DS_Store differ diff --git a/tests/core/pm-module/.DS_Store b/tests/core/pm-module/.DS_Store new file mode 100644 index 0000000000..4424dcbf8d Binary files /dev/null and b/tests/core/pm-module/.DS_Store differ diff --git a/tests/ens/test_setup_address.py b/tests/ens/test_setup_address.py index 022c9337aa..6ac7e63d64 100644 --- a/tests/ens/test_setup_address.py +++ b/tests/ens/test_setup_address.py @@ -1,4 +1,3 @@ - import pytest from unittest.mock import ( patch, @@ -32,12 +31,7 @@ '0x2a7ac1c833d35677c2ff34a908951de142cc1653de6080ad4e38f4c9cc00aafe', ), ( - 'tester', - 'tester.eth', - '0x2a7ac1c833d35677c2ff34a908951de142cc1653de6080ad4e38f4c9cc00aafe', - ), - ( - 'TESTER', + 'TESTER.eth', 'TESTER.eth', '0x2a7ac1c833d35677c2ff34a908951de142cc1653de6080ad4e38f4c9cc00aafe', ), @@ -63,27 +57,19 @@ 'lots.of.subdomains.tester.eth', '0x0d62a759aa1f1c9680de8603a12a5eb175cd1bfa79426229868eba99f4dce692', ), - ( - 'lots.of.subdomains.tester', - 'lots.of.subdomains.tester.eth', - '0x0d62a759aa1f1c9680de8603a12a5eb175cd1bfa79426229868eba99f4dce692', - ), ], ) def test_set_address(ens, name, full_name, namehash_hex, TEST_ADDRESS): assert ens.address(name) is None - owner = ens.owner('tester') + owner = ens.owner('tester.eth') ens.setup_address(name, TEST_ADDRESS) assert is_same_address(ens.address(name), TEST_ADDRESS) - # check that .eth is only appended if guess_tld is True namehash = Web3.toBytes(hexstr=namehash_hex) normal_name = ens.nameprep(full_name) if ens.nameprep(name) == normal_name: - assert is_same_address(ens.address(name, guess_tld=False), TEST_ADDRESS) - else: - assert ens.address(name, guess_tld=False) is None + assert is_same_address(ens.address(name), TEST_ADDRESS) # check that the correct namehash is set: assert is_same_address(ens.resolver(normal_name).addr(namehash), TEST_ADDRESS) @@ -98,7 +84,7 @@ def test_set_address(ens, name, full_name, namehash_hex, TEST_ADDRESS): @pytest.mark.parametrize( 'name, equivalent', [ - ('TESTER', 'tester.eth'), + ('TESTER.eth', 'tester.eth'), ('unicÖde.tester.eth', 'unicöde.tester.eth'), ], ) @@ -165,12 +151,15 @@ def getowner(name): def test_set_resolver_leave_default(ens, TEST_ADDRESS): - owner = ens.owner('tester') + owner = ens.owner('tester.eth') ens.setup_address('leave-default-resolver.tester.eth', TEST_ADDRESS) eth = ens.web3.eth num_transactions = eth.getTransactionCount(owner) - ens.setup_address('leave-default-resolver.tester', '0x5B2063246F2191f18F2675ceDB8b28102e957458') + ens.setup_address( + 'leave-default-resolver.tester.eth', + '0x5B2063246F2191f18F2675ceDB8b28102e957458' + ) # should skip setting the owner and setting the default resolver, and only # set the name in the default resolver to point to the new address diff --git a/tests/ens/test_setup_name.py b/tests/ens/test_setup_name.py index a907289b07..e1ee9c0d2d 100644 --- a/tests/ens/test_setup_name.py +++ b/tests/ens/test_setup_name.py @@ -1,4 +1,3 @@ - import pytest from ens.main import ( @@ -28,12 +27,7 @@ def TEST_ADDRESS(address_conversion_func): '2a7ac1c833d35677c2ff34a908951de142cc1653de6080ad4e38f4c9cc00aafe', ), ( - 'tester', - 'tester.eth', - '2a7ac1c833d35677c2ff34a908951de142cc1653de6080ad4e38f4c9cc00aafe', - ), - ( - 'TESTER', + 'TESTER.eth', 'tester.eth', '2a7ac1c833d35677c2ff34a908951de142cc1653de6080ad4e38f4c9cc00aafe', ), @@ -58,25 +52,16 @@ def TEST_ADDRESS(address_conversion_func): 'lots.of.subdomains.tester.eth', '0d62a759aa1f1c9680de8603a12a5eb175cd1bfa79426229868eba99f4dce692', ), - ( - 'lots.of.subdomains.tester', - 'lots.of.subdomains.tester.eth', - '0d62a759aa1f1c9680de8603a12a5eb175cd1bfa79426229868eba99f4dce692', - ), ], ) def test_setup_name(ens, name, normalized_name, namehash_hex): address = ens.web3.eth.accounts[3] assert not ens.name(address) - owner = ens.owner('tester') + owner = ens.owner('tester.eth') ens.setup_name(name, address) assert ens.name(address) == normalized_name - # check that .eth is only appended if guess_tld is True - if ens.nameprep(name) != normalized_name: - assert ens.address(name, guess_tld=False) is None - # check that the correct namehash is set: node = Web3.toBytes(hexstr=namehash_hex) assert ens.resolver(normalized_name).addr(node) == address