From 0df8363fc6773ee7a50c69d440c6b58eae82e240 Mon Sep 17 00:00:00 2001 From: Nick Johnson <arachnid@notdot.net> Date: Sat, 13 May 2017 16:53:40 +0100 Subject: [PATCH] ERC: Ethereum Name Service reverse resolution support --- EIPS/eip-181.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 EIPS/eip-181.md diff --git a/EIPS/eip-181.md b/EIPS/eip-181.md new file mode 100644 index 00000000..66b08a23 --- /dev/null +++ b/EIPS/eip-181.md @@ -0,0 +1,104 @@ +<pre> + EIP: 181 + Title: ENS support for reverse resolution of Ethereum addresses + Author: Nick Johnson <arachnid@notdot.net> + Status: Draft + Type: Informational + Created: 2016-12-01 +</pre> + +# Abstract +This EIP specifies a TLD, registrar, and resolver interface for reverse resolution of Ethereum addresses using ENS. This permits associating a human-readable name with any Ethereum blockchain address. Resolvers can be certain that the reverse record was published by the owner of the Ethereum address in question. + +# Motivation +While name services are mostly used for forward resolution - going from human-readable identifiers to machine-readable ones - there are many use-cases in which reverse resolution is useful as well: + + - Applications that allow users to monitor accounts benefit from showing the name of an account instead of its address, even if it was originally added by address. + - Attaching metadata such as descriptive information to an address allows retrieving this information regardless of how the address was originally discovered. + - Anyone can configure a name to resolve to an address, regardless of ownership of that address. Reverse records allow the owner of an address to claim a name as authoritative for that address. + +# Specification +Reverse ENS records are stored in the ENS hierarchy in the same fashion as regular records, under a reserved domain, `addr.reverse`. To generate the ENS name for a given account's reverse records, convert the account to hexadecimal representation in lower-case, and append `addr.reverse`. For instance, the ENS registry's address at `0x112234455c3a32fd11230c42e7bccd4a84e02010` has any reverse records stored at `112234455c3a32fd11230c42e7bccd4a84e02010.addr.reverse`. + +Note that this means that contracts wanting to do dynamic reverse resolution of addresses will need to perform hex encoding in the contract. + +## Registrar +The owner of the `addr.reverse` domain will be a registrar that permits the caller to take ownership of +the reverse record for their own address. It provides the following method: + + function claim(address owner) returns (bytes32 node); + +When called by account `x` it will instruct the ENS registry to transfer ownership of the name `hex(x) + '.addr.reverse'` to the provided address, and return the namehash of the ENS record thus transferred. + +Allowing the caller to specify an owner other than themselves for the relevant node facilitates contracts that need accurate reverse ENS entries delegating this to their creators with a minimum of code inside their constructor: + + reverseRegistrar.claim(msg.sender) + +## Resolver interface +A new resolver interface is defined, consisting of the following method: + + function name(bytes32 node) constant returns (string); + +Resolvers that implement this interface must return a valid ENS name for the requested node, or the empty string if no name is defined for the requested node. + +The interface ID of this interface is 0x691f3431. + +Future EIPs may specify more record types appropriate to reverse ENS records. + +# Appendix 1: Registrar implementation + +This registrar, written in Solidity, implements the specifications outlined above. + + pragma solidity ^0.4.0; + + import 'interface.sol'; + + contract ReverseRegistrar { + AbstractENS public ens; + bytes32 public rootNode; + + /** + * @dev Constructor + * @param ensAddr The address of the ENS registry. + * @param node The node hash that this registrar governs. + */ + function ReverseRegistrar(address ensAddr, bytes32 node) { + ens = AbstractENS(ensAddr); + rootNode = node; + } + + /** + * @dev Transfers ownership of the reverse ENS record associated with the + * calling account. + * @param owner The address to set as the owner of the reverse record in ENS. + * @return The ENS node hash of the reverse record. + */ + function claim(address owner) returns (bytes32 node) { + var label = sha3HexAddress(msg.sender); + ens.setSubnodeOwner(rootNode, label, owner); + return sha3(rootNode, label); + } + + /** + * @dev An optimised function to compute the sha3 of the lower-case + * hexadecimal representation of an Ethereum address. + * @param addr The address to hash + * @return The SHA3 hash of the lower-case hexadecimal encoding of the + * input address. + */ + function sha3HexAddress(address addr) constant returns (bytes32 ret) { + assembly { + let lookup := 0x3031323334353637383961626364656600000000000000000000000000000000 + let i := 40 + loop: + i := sub(i, 1) + mstore8(i, byte(and(addr, 0xf), lookup)) + addr := div(addr, 0x10) + i := sub(i, 1) + mstore8(i, byte(and(addr, 0xf), lookup)) + addr := div(addr, 0x10) + jumpi(loop, i) + ret := sha3(0, 40) + } + } + }