Merge pull request #630 from Arachnid/181

ERC: Ethereum Name Service reverse resolution support
This commit is contained in:
Nick Johnson 2017-05-14 09:13:19 +01:00 committed by GitHub
commit e0a61ffc5e
1 changed files with 105 additions and 0 deletions

105
EIPS/eip-181.md Normal file
View File

@ -0,0 +1,105 @@
<pre>
EIP: 181
Title: ENS support for reverse resolution of Ethereum addresses
Author: Nick Johnson <arachnid@notdot.net>
Status: Final
Type: Standard Track
Category: ERC
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)
}
}
}