ERC-1185 Storing DNS Records in ENS (Storage of DNS Records in ENS)

Review · Names & metadata · created 2018-06-26

A resolver standard for storing and looking up DNS records inside Ethereum Name Service (ENS) contracts. It lets ENS serve as a trustworthy store of DNS information.

Why it is needed

DNS, the internet's addressing system, has a hierarchical structure in which higher-level authorities control the availability of the domains beneath them. For example, whoever administers .org determines whether ethereum.org stays alive. Traditional DNS also entangles domain ownership with the role of authoritatively serving that domain's information. Using the Ethereum Name Service (ENS) as the store separates these two roles. A domain owner can have full control over their own DNS records and can irrevocably hand off a subdomain to another party through a smart contract. But ENS had no common specification for the format in which DNS records are written and read, so a standardized resolver profile was needed.

What to implement

In depth

Stored per record set, not per zone

Traditional DNS is a zone-based system that keeps every record of a zone together in a single file. That's simple and makes updates atomic, but porting it directly to ENS would make even small changes expensive in gas. So this resolver operates at the level of record sets, each defined by the tuple (domain, name, resource record type). For example, (example.com, www.example.com, A) refers to the A record set for the name www.example.com under the domain example.com, and if the A records are 1.2.3.4 and 5.6.7.8, that record set holds two values. Because it operates at the record-set level, some DNS features such as zone transfers or DNSSEC cannot be fully supported. A zone-level resolver could also be built, but updating it would be very expensive, so this EIP does not cover that case.

setDNSRecords: writes and deletes in a single function

setDNSRecords(bytes32 node, bytes data) sets, updates, or deletes one or more DNS records for the given node. The function signature is 0x0af179d7. node is the namehash (as defined in ERC-137) of the ENS domain's full name, and data is the records encoded in DNS wire format. Records submitted with no value are deleted. Records belonging to the same RRset must be placed consecutively within data; otherwise a later RRset will overwrite an earlier one. The reference implementation's comments illustrate this with an example where a CNAME inserted between two A records causes the second A record to overwrite the first.

clearDNSZone: clears an entire zone at once

clearDNSZone(bytes32 node) removes all DNS records for the domain. The function signature is 0xad5780af. Records could also be deleted one at a time with setDNSRecords, but the resolver has no way to enumerate a domain's records, so the owner would need to remember every record they set, and it could take multiple transactions. clearDNSZone removes an entire zone's worth of information in a single operation. The reference implementation achieves this by bumping a per-node version number, letting a user effectively wipe an entire zone even if they've forgotten which records they set.

dnsRecords and hasDNSRecords: the two lookup functions

dnsRecords(bytes32 node, bytes32 name, uint16 resource) returns all records matching the node, name, and resource in DNS wire format, or nothing if none exist. The signature is 0x2461e851. name is the keccak256() hash of the record name in DNS wire format, and resource is the resource record ID as defined by RFC 1035 and its successor RFCs. hasDNSRecords(bytes32 node, bytes32 name) returns true if the name has any record at all. The signature is 0x4cbf6ba4. This function is needed by DNS resolvers that handle the wildcard resources defined in RFC 4592.

Reference implementation: version mapping and zonehash

The reference implementation stores records as binary RRSETs in a node => version => name => resource => data mapping, and separately counts records per name in nameEntriesCount for use in wildcard lookups. It emits a DNSRecordChanged event when a record changes, a DNSRecordDeleted event when one is deleted, and a DNSZoneCleared event when a zone is reset. Separately, setZonehash and zonehash functions manage the zonehash, which is an ERC-1577 content hash (in binary format) pointing to a resource containing a single zone file. The interface IDs are 0xa8fa5682 for DNS records and 0x5c47637c for DNS zones.

A new profile that doesn't conflict with existing interfaces

This standard only adds a new resolver profile conforming to the ENS resolver specification defined by ERC-137; it does not modify any existing profile or interface, so there are no backward compatibility concerns. The original text gives as rationale that with decentralized DNS, any domain with a record in ENS can be looked up directly, with no higher-level authority in control. This proposal is currently in Review status, so its content may still change.

Things to watch out for

Original ERC · ← ERCs