Update EIP181 with new functions and new resolver implementation (#638)

This commit is contained in:
Nick Johnson 2018-10-15 13:25:37 +01:00 committed by GitHub
parent 617ab2d0c3
commit e6e67ce6f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 116 additions and 15 deletions

View File

@ -24,17 +24,25 @@ Reverse ENS records are stored in the ENS hierarchy in the same fashion as regul
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:
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 methods:
function claim(address owner) returns (bytes32 node);
### 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.
When called by account `x`, instructs 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)
### function claimWithResolver(address owner, address resolver) returns (bytes32 node)
When called by account `x`, instructs the ENS registry to set the resolver of the name `hex(x) + '.addr.reverse' to the specified resolver, then transfer ownership of the name to the provided address, and return the namehash of the ENS record thus transferred. This method facilitates setting up a custom resolver and owner in fewer transactions than would be required if calling `claim`.
### function setName(string name) returns (bytes32 node)
When called by account `x`, sets the resolver for the name `hex(x) + '.addr.reverse'` to a default resolver, and sets the name record on that name to the specified name. This method facilitates setting up simple reverse records for users in a single transaction.
## Resolver interface
A new resolver interface is defined, consisting of the following method:
@ -50,22 +58,64 @@ Future EIPs may specify more record types appropriate to reverse ENS records.
This registrar, written in Solidity, implements the specifications outlined above.
pragma solidity ^0.4.0;
pragma solidity ^0.4.10;
import 'interface.sol';
import "./AbstractENS.sol";
contract ReverseRegistrar {
contract Resolver {
function setName(bytes32 node, string name) public;
}
/**
* @dev Provides a default implementation of a resolver for reverse records,
* which permits only the owner to update it.
*/
contract DefaultReverseResolver is Resolver {
AbstractENS public ens;
bytes32 public rootNode;
mapping(bytes32=>string) public name;
/**
* @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;
function DefaultReverseResolver(AbstractENS ensAddr) {
ens = ensAddr;
}
/**
* @dev Only permits calls by the reverse registrar.
* @param node The node permission is required for.
*/
modifier owner_only(bytes32 node) {
require(msg.sender == ens.owner(node));
_;
}
/**
* @dev Sets the name for a node.
* @param node The node to update.
* @param _name The name to set.
*/
function setName(bytes32 node, string _name) public owner_only(node) {
name[node] = _name;
}
}
contract ReverseRegistrar {
// namehash('addr.reverse')
bytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
AbstractENS public ens;
Resolver public defaultResolver;
/**
* @dev Constructor
* @param ensAddr The address of the ENS registry.
* @param resolverAddr The address of the default reverse resolver.
*/
function ReverseRegistrar(AbstractENS ensAddr, Resolver resolverAddr) {
ens = ensAddr;
defaultResolver = resolverAddr;
}
/**
@ -75,9 +125,59 @@ This registrar, written in Solidity, implements the specifications outlined abov
* @return The ENS node hash of the reverse record.
*/
function claim(address owner) returns (bytes32 node) {
return claimWithResolver(owner, 0);
}
/**
* @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.
* @param resolver The address of the resolver to set; 0 to leave unchanged.
* @return The ENS node hash of the reverse record.
*/
function claimWithResolver(address owner, address resolver) returns (bytes32 node) {
var label = sha3HexAddress(msg.sender);
ens.setSubnodeOwner(rootNode, label, owner);
return sha3(rootNode, label);
node = sha3(ADDR_REVERSE_NODE, label);
var currentOwner = ens.owner(node);
// Update the resolver if required
if(resolver != 0 && resolver != ens.resolver(node)) {
// Transfer the name to us first if it's not already
if(currentOwner != address(this)) {
ens.setSubnodeOwner(ADDR_REVERSE_NODE, label, this);
currentOwner = address(this);
}
ens.setResolver(node, resolver);
}
// Update the owner if required
if(currentOwner != owner) {
ens.setSubnodeOwner(ADDR_REVERSE_NODE, label, owner);
}
return node;
}
/**
* @dev Sets the `name()` record for the reverse ENS record associated with
* the calling account. First updates the resolver to the default reverse
* resolver if necessary.
* @param name The name to set for this address.
* @return The ENS node hash of the reverse record.
*/
function setName(string name) returns (bytes32 node) {
node = claimWithResolver(this, defaultResolver);
defaultResolver.setName(node, name);
return node;
}
/**
* @dev Returns the node hash for a given account's reverse records.
* @param addr The address to hash
* @return The ENS node hash.
*/
function node(address addr) constant returns (bytes32 ret) {
return sha3(ADDR_REVERSE_NODE, sha3HexAddress(addr));
}
/**
@ -87,7 +187,8 @@ This registrar, written in Solidity, implements the specifications outlined abov
* @return The SHA3 hash of the lower-case hexadecimal encoding of the
* input address.
*/
function sha3HexAddress(address addr) constant returns (bytes32 ret) {
function sha3HexAddress(address addr) private returns (bytes32 ret) {
addr; ret; // Stop warning us about unused variables
assembly {
let lookup := 0x3031323334353637383961626364656600000000000000000000000000000000
let i := 40