eip-137.md
1 --- 2 eip: 137 3 title: Ethereum Domain Name Service - Specification 4 author: Nick Johnson <arachnid@notdot.net> 5 status: Final 6 type: Standards Track 7 category: ERC 8 created: 2016-04-04 9 --- 10 11 # Abstract 12 13 This draft EIP describes the details of the Ethereum Name Service, a proposed protocol and ABI definition that provides flexible resolution of short, human-readable names to service and resource identifiers. This permits users and developers to refer to human-readable and easy to remember names, and permits those names to be updated as necessary when the underlying resource (contract, content-addressed data, etc) changes. 14 15 The goal of domain names is to provide stable, human-readable identifiers that can be used to specify network resources. In this way, users can enter a memorable string, such as 'vitalik.wallet' or 'www.mysite.swarm', and be directed to the appropriate resource. The mapping between names and resources may change over time, so a user may change wallets, a website may change hosts, or a swarm document may be updated to a new version, without the domain name changing. Further, a domain need not specify a single resource; different record types allow the same domain to reference different resources. For instance, a browser may resolve 'mysite.swarm' to the IP address of its server by fetching its A (address) record, while a mail client may resolve the same address to a mail server by fetching its MX (mail exchanger) record. 16 # Motivation 17 18 Existing [specifications](https://github.com/ethereum/wiki/wiki/Registrar-ABI) and [implementations](https://ethereum.gitbooks.io/frontier-guide/content/registrar_services.html) for name resolution in Ethereum provide basic functionality, but suffer several shortcomings that will significantly limit their long-term usefulness: 19 - A single global namespace for all names with a single 'centralised' resolver. 20 - Limited or no support for delegation and sub-names/sub-domains. 21 - Only one record type, and no support for associating multiple copies of a record with a domain. 22 - Due to a single global implementation, no support for multiple different name allocation systems. 23 - Conflation of responsibilities: Name resolution, registration, and whois information. 24 25 Use-cases that these features would permit include: 26 - Support for subnames/sub-domains - eg, live.mysite.tld and forum.mysite.tld. 27 - Multiple services under a single name, such as a DApp hosted in Swarm, a Whisper address, and a mail server. 28 - Support for DNS record types, allowing blockchain hosting of 'legacy' names. This would permit an Ethereum client such as Mist to resolve the address of a traditional website, or the mail server for an email address, from a blockchain name. 29 - DNS gateways, exposing ENS domains via the Domain Name Service, providing easier means for legacy clients to resolve and connect to blockchain services. 30 31 The first two use-cases, in particular, can be observed everywhere on the present-day internet under DNS, and we believe them to be fundamental features of a name service that will continue to be useful as the Ethereum platform develops and matures. 32 33 The normative parts of this document does not specify an implementation of the proposed system; its purpose is to document a protocol that different resolver implementations can adhere to in order to facilitate consistent name resolution. An appendix provides sample implementations of resolver contracts and libraries, which should be treated as illustrative examples only. 34 35 Likewise, this document does not attempt to specify how domains should be registered or updated, or how systems can find the owner responsible for a given domain. Registration is the responsibility of registrars, and is a governance matter that will necessarily vary between top-level domains. 36 37 Updating of domain records can also be handled separately from resolution. Some systems, such as swarm, may require a well defined interface for updating domains, in which event we anticipate the development of a standard for this. 38 # Specification 39 ## Overview 40 41 The ENS system comprises three main parts: 42 - The ENS registry 43 - Resolvers 44 - Registrars 45 46 The registry is a single contract that provides a mapping from any registered name to the resolver responsible for it, and permits the owner of a name to set the resolver address, and to create subdomains, potentially with different owners to the parent domain. 47 48 Resolvers are responsible for performing resource lookups for a name - for instance, returning a contract address, a content hash, or IP address(es) as appropriate. The resolver specification, defined here and extended in other EIPs, defines what methods a resolver may implement to support resolving different types of records. 49 50 Registrars are responsible for allocating domain names to users of the system, and are the only entities capable of updating the ENS; the owner of a node in the ENS registry is its registrar. Registrars may be contracts or externally owned accounts, though it is expected that the root and top-level registrars, at a minimum, will be implemented as contracts. 51 52 Resolving a name in ENS is a two-step process. First, the ENS registry is called with the name to resolve, after hashing it using the procedure described below. If the record exists, the registry returns the address of its resolver. Then, the resolver is called, using the method appropriate to the resource being requested. The resolver then returns the desired result. 53 54 For example, suppose you wish to find the address of the token contract associated with 'beercoin.eth'. First, get the resolver: 55 56 ```javascript 57 var node = namehash("beercoin.eth"); 58 var resolver = ens.resolver(node); 59 ``` 60 61 Then, ask the resolver for the address for the contract: 62 63 ```javascript 64 var address = resolver.addr(node); 65 ``` 66 67 Because the `namehash` procedure depends only on the name itself, this can be precomputed and inserted into a contract, removing the need for string manipulation, and permitting O(1) lookup of ENS records regardless of the number of components in the raw name. 68 ## Name Syntax 69 70 ENS names must conform to the following syntax: 71 72 <pre><domain> ::= <label> | <domain> "." <label> 73 <label> ::= any valid string label per [UTS46](https://unicode.org/reports/tr46/) 74 </pre> 75 76 In short, names consist of a series of dot-separated labels. Each label must be a valid normalised label as described in [UTS46](https://unicode.org/reports/tr46/) with the options `transitional=false` and `useSTD3AsciiRules=true`. For Javascript implementations, a [library](https://www.npmjs.com/package/idna-uts46) is available that normalises and checks names. 77 78 Note that while upper and lower case letters are allowed in names, the UTS46 normalisation process case-folds labels before hashing them, so two names with different case but identical spelling will produce the same namehash. 79 80 Labels and domains may be of any length, but for compatibility with legacy DNS, it is recommended that labels be restricted to no more than 64 characters each, and complete ENS names to no more than 255 characters. For the same reason, it is recommended that labels do not start or end with hyphens, or start with digits. 81 82 ## namehash algorithm 83 84 Before being used in ENS, names are hashed using the 'namehash' algorithm. This algorithm recursively hashes components of the name, producing a unique, fixed-length string for any valid input domain. The output of namehash is referred to as a 'node'. 85 86 Pseudocode for the namehash algorithm is as follows: 87 88 ``` 89 def namehash(name): 90 if name == '': 91 return '\0' * 32 92 else: 93 label, _, remainder = name.partition('.') 94 return sha3(namehash(remainder) + sha3(label)) 95 ``` 96 97 Informally, the name is split into labels, each label is hashed. Then, starting with the last component, the previous output is concatenated with the label hash and hashed again. The first component is concatenated with 32 '0' bytes. Thus, 'mysite.swarm' is processed as follows: 98 99 ``` 100 node = '\0' * 32 101 node = sha3(node + sha3('swarm')) 102 node = sha3(node + sha3('mysite')) 103 ``` 104 105 Implementations should conform to the following test vectors for namehash: 106 107 namehash('') = 0x0000000000000000000000000000000000000000000000000000000000000000 108 namehash('eth') = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae 109 namehash('foo.eth') = 0xde9b09fd7c5f901e23a3f19fecc54828e9c848539801e86591bd9801b019f84f 110 111 ## Registry specification 112 113 The ENS registry contract exposes the following functions: 114 115 ```solidity 116 function owner(bytes32 node) constant returns (address); 117 ``` 118 119 Returns the owner (registrar) of the specified node. 120 121 ```solidity 122 function resolver(bytes32 node) constant returns (address); 123 ``` 124 125 Returns the resolver for the specified node. 126 127 ```solidity 128 function ttl(bytes32 node) constant returns (uint64); 129 ``` 130 131 Returns the time-to-live (TTL) of the node; that is, the maximum duration for which a node's information may be cached. 132 133 ```solidity 134 function setOwner(bytes32 node, address owner); 135 ``` 136 137 Transfers ownership of a node to another registrar. This function may only be called by the current owner of `node`. A successful call to this function logs the event `Transfer(bytes32 indexed, address)`. 138 139 ```solidity 140 function setSubnodeOwner(bytes32 node, bytes32 label, address owner); 141 ``` 142 143 Creates a new node, `sha3(node, label)` and sets its owner to `owner`, or updates the node with a new owner if it already exists. This function may only be called by the current owner of `node`. A successful call to this function logs the event `NewOwner(bytes32 indexed, bytes32 indexed, address)`. 144 145 ```solidity 146 function setResolver(bytes32 node, address resolver); 147 ``` 148 149 Sets the resolver address for `node`. This function may only be called by the owner of `node`. A successful call to this function logs the event `NewResolver(bytes32 indexed, address)`. 150 151 ```solidity 152 function setTTL(bytes32 node, uint64 ttl); 153 ``` 154 155 Sets the TTL for a node. A node's TTL applies to the 'owner' and 'resolver' records in the registry, as well as to any information returned by the associated resolver. 156 ## Resolver specification 157 158 Resolvers may implement any subset of the record types specified here. Where a record types specification requires a resolver to provide multiple functions, the resolver MUST implement either all or none of them. Resolvers MUST specify a fallback function that throws. 159 160 Resolvers have one mandatory function: 161 162 ```solidity 163 function supportsInterface(bytes4 interfaceID) constant returns (bool) 164 ``` 165 166 The `supportsInterface` function is documented in [EIP 165](https://github.com/ethereum/EIPs/issues/165), and returns true if the resolver implements the interface specified by the provided 4 byte identifier. An interface identifier consists of the XOR of the function signature hashes of the functions provided by that interface; in the degenerate case of single-function interfaces, it is simply equal to the signature hash of that function. If a resolver returns `true` for `supportsInterface()`, it must implement the functions specified in that interface. 167 168 `supportsInterface` must always return true for `0x01ffc9a7`, which is the interface ID of `supportsInterface` itself. 169 170 Currently standardised resolver interfaces are specified in the table below. 171 172 The following interfaces are defined: 173 174 | Interface name | Interface hash | Specification | 175 | --- | --- | --- | 176 | `addr` | 0x3b3b57de | [Contract address](#addr) | 177 | `name` | 0x691f3431 | #181 | 178 | `ABI` | 0x2203ab56 | #205 | 179 | `pubkey` | 0xc8690233 | #619 | 180 181 EIPs may define new interfaces to be added to this registry. 182 183 ### <a name="addr"></a>Contract Address Interface 184 185 Resolvers wishing to support contract address resources must provide the following function: 186 187 ```solidity 188 function addr(bytes32 node) constant returns (address); 189 ``` 190 191 If the resolver supports `addr` lookups but the requested node does not have an addr record, the resolver MUST return the zero address. 192 193 Clients resolving the `addr` record MUST check for a zero return value, and treat this in the same manner as a name that does not have a resolver specified - that is, refuse to send funds to or interact with the address. Failure to do this can result in users accidentally sending funds to the 0 address. 194 195 Changes to an address MUST trigger the following event: 196 197 ```solidity 198 event AddrChanged(bytes32 indexed node, address a); 199 ``` 200 # Appendix A: Registry Implementation 201 202 ```solidity 203 contract ENS { 204 struct Record { 205 address owner; 206 address resolver; 207 uint64 ttl; 208 } 209 210 mapping(bytes32=>Record) records; 211 212 event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); 213 event Transfer(bytes32 indexed node, address owner); 214 event NewResolver(bytes32 indexed node, address resolver); 215 216 modifier only_owner(bytes32 node) { 217 if(records[node].owner != msg.sender) throw; 218 _ 219 } 220 221 function ENS(address owner) { 222 records[0].owner = owner; 223 } 224 225 function owner(bytes32 node) constant returns (address) { 226 return records[node].owner; 227 } 228 229 function resolver(bytes32 node) constant returns (address) { 230 return records[node].resolver; 231 } 232 233 function ttl(bytes32 node) constant returns (uint64) { 234 return records[node].ttl; 235 } 236 237 function setOwner(bytes32 node, address owner) only_owner(node) { 238 Transfer(node, owner); 239 records[node].owner = owner; 240 } 241 242 function setSubnodeOwner(bytes32 node, bytes32 label, address owner) only_owner(node) { 243 var subnode = sha3(node, label); 244 NewOwner(node, label, owner); 245 records[subnode].owner = owner; 246 } 247 248 function setResolver(bytes32 node, address resolver) only_owner(node) { 249 NewResolver(node, resolver); 250 records[node].resolver = resolver; 251 } 252 253 function setTTL(bytes32 node, uint64 ttl) only_owner(node) { 254 NewTTL(node, ttl); 255 records[node].ttl = ttl; 256 } 257 } 258 ``` 259 # Appendix B: Sample Resolver Implementations 260 ### Built-in resolver 261 262 The simplest possible resolver is a contract that acts as its own name resolver by implementing the contract address resource profile: 263 264 ```solidity 265 contract DoSomethingUseful { 266 // Other code 267 268 function addr(bytes32 node) constant returns (address) { 269 return this; 270 } 271 272 function supportsInterface(bytes4 interfaceID) constant returns (bool) { 273 return interfaceID == 0x3b3b57de || interfaceID == 0x01ffc9a7; 274 } 275 276 function() { 277 throw; 278 } 279 } 280 ``` 281 282 Such a contract can be inserted directly into the ENS registry, eliminating the need for a separate resolver contract in simple use-cases. However, the requirement to 'throw' on unknown function calls may interfere with normal operation of some types of contract. 283 284 ### Standalone resolver 285 286 A basic resolver that implements the contract address profile, and allows only its owner to update records: 287 288 ```solidity 289 contract Resolver { 290 event AddrChanged(bytes32 indexed node, address a); 291 292 address owner; 293 mapping(bytes32=>address) addresses; 294 295 modifier only_owner() { 296 if(msg.sender != owner) throw; 297 _ 298 } 299 300 function Resolver() { 301 owner = msg.sender; 302 } 303 304 function addr(bytes32 node) constant returns(address) { 305 return addresses[node]; 306 } 307 308 function setAddr(bytes32 node, address addr) only_owner { 309 addresses[node] = addr; 310 AddrChanged(node, addr); 311 } 312 313 function supportsInterface(bytes4 interfaceID) constant returns (bool) { 314 return interfaceID == 0x3b3b57de || interfaceID == 0x01ffc9a7; 315 } 316 317 function() { 318 throw; 319 } 320 } 321 ``` 322 323 After deploying this contract, use it by updating the ENS registry to reference this contract for a name, then calling `setAddr()` with the same node to set the contract address it will resolve to. 324 ### Public resolver 325 326 Similar to the resolver above, this contract only supports the contract address profile, but uses the ENS registry to determine who should be allowed to update entries: 327 328 ```solidity 329 contract PublicResolver { 330 event AddrChanged(bytes32 indexed node, address a); 331 event ContentChanged(bytes32 indexed node, bytes32 hash); 332 333 ENS ens; 334 mapping(bytes32=>address) addresses; 335 336 modifier only_owner(bytes32 node) { 337 if(ens.owner(node) != msg.sender) throw; 338 _ 339 } 340 341 function PublicResolver(address ensAddr) { 342 ens = ENS(ensAddr); 343 } 344 345 function addr(bytes32 node) constant returns (address ret) { 346 ret = addresses[node]; 347 } 348 349 function setAddr(bytes32 node, address addr) only_owner(node) { 350 addresses[node] = addr; 351 AddrChanged(node, addr); 352 } 353 354 function supportsInterface(bytes4 interfaceID) constant returns (bool) { 355 return interfaceID == 0x3b3b57de || interfaceID == 0x01ffc9a7; 356 } 357 358 function() { 359 throw; 360 } 361 } 362 ``` 363 # Appendix C: Sample Registrar Implementation 364 365 This registrar allows users to register names at no cost if they are the first to request them. 366 367 ```solidity 368 contract FIFSRegistrar { 369 ENS ens; 370 bytes32 rootNode; 371 372 function FIFSRegistrar(address ensAddr, bytes32 node) { 373 ens = ENS(ensAddr); 374 rootNode = node; 375 } 376 377 function register(bytes32 subnode, address owner) { 378 var node = sha3(rootNode, subnode); 379 var currentOwner = ens.owner(node); 380 if(currentOwner != 0 && currentOwner != msg.sender) 381 throw; 382 383 ens.setSubnodeOwner(rootNode, subnode, owner); 384 } 385 } 386 ```