From b57354b8e36082c38ac960c1e77b8c377d7f1d4f Mon Sep 17 00:00:00 2001 From: Jim McDonald Date: Tue, 26 Jun 2018 19:52:33 +0100 Subject: [PATCH 1/7] DNS resolver profile for ENS --- EIPS/eip-draft_ens_dns.md | 105 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 EIPS/eip-draft_ens_dns.md diff --git a/EIPS/eip-draft_ens_dns.md b/EIPS/eip-draft_ens_dns.md new file mode 100644 index 00000000000000..0543ea4be3c570 --- /dev/null +++ b/EIPS/eip-draft_ens_dns.md @@ -0,0 +1,105 @@ +eip: +title: Storage of DNS Records in ENS +author: Jim McDonald +status: Draft +type: Standards Track +category ERC +created: 2018-06-26 +requires: #137 + +## Abstract +This EIP defines a resolver profile for ENS that provides features for storage and lookup of DNS records. This allows ENS to be used as a store of authoritative DNS information. + +## Motivation +ENS is a perfect store for DNS records. It provides the distributed authority of DNS without conflating ownership and serving of information. With ENS, the owner of a domain has full control over their own DNS records. Separately, ENS has the ability (through smart contracts) for a domain's subdomains to be irrevocably assigned to another entity. + +## Specification + +The resolver profile to support DNS on ENS builds on the standalone resolver as defined in #137. + +Traditionally, DNS is a zone-based system in that all of the records for a zone are kept together in the same file. This has the benefit of simplicity and atomicity of zone updates, but when transposed to ENS can result in significant gas costs for simple changes. As a result, the resolver provides the ability to store either zone-based or record-based DNS information for a given domain, each with their own set of functions for managing the information. + +The primary reason that a user might choose to use the zone-based functions is if the zone uses information that spans multiple records and requires strict ordering (for example DNSSEC with NSSEC/NSSEC3 records), so an unordered record-based storage system is not possible. If this is not a consideration then record-based storage is generally cheaper and more flexible. + +A DNS zone is uniquely identified by the domain for which it contains records. A DNS record set is uniquely identified by the domain, label and resource record type. + +One of zone-based or record-based functions should be chosen for a given ENS domain. If both are used then results from a DNS resolver may be inconsistent. + +The DNS resolver interface consists of three functions to update DNS information and three functions to query DNS information. + +### setDNSRecords(bytes32 node, bytes data) + +This function is used when using record-based storage. + +`setDNSRecords()` sets, updates or clears 1 or more DNS records for a given node. + +The arguments for the function are as follows: + - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 + - data: 1 or more DNS records in DNS wire format. + +### dnsRecord(bytes32 node, bytes32 name, uint16 resource) + +This function is used when using record-based storage. + +`dnsRecord()` obtains the DNS records for a given node, name and resource. + +The arguments for the function are as follows: + - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 + - name: the `keccak256()` hash of the name of the record in DNS wire format. + - resource: the resource record ID. Resource record IDs are defined in https://en.wikipedia.org/wiki/List\_of\_DNS\_record\_types + +The function returns all matching records in DNS wire format. If there are no records present the function will return nothing. + +### hasDNSRecords(bytes32 node, bytes32 name) + +This function is used when using record-based storage. + +`hasDNSRecords()` reports if there are any records for the provided name in the domain. This is needed by DNS resolvers when working with wildcard resources. + +The arguments for the function are as follows: + - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 + - name: the `keccak256()` hash of the name of the record in DNS wire format. + +The function returns `true` if there are any records for the provided node and name, otherwise `false`. + +### setDNSZone(bytes32 node, bytes data) + +This function is used when using zone-based storage. + +`setDNSZone()` sets or updates the DNS zone file for a given domain. + +The arguments for the function are as follows: + - node: the nodehash of the fully-qualified domain in ENS for which to set the zone. Node hashes are defined in #137 + - data: the entire zone in DNS wire format + +### dnsZone(bytes32 node) + +This function is used when using zone-based storage. + +`dnsZone()` obtains the DNS zone file for a given domain. + +The argument for the function is as follows: + - node: the nodehash of the fully-qualified domain in ENS for which to set the zone. Node hashes are defined in #137 + +The function returns the entire zone in DNS wire format. If there is no zone present the function will return nothing. + +### clearDNSZone(bytes32 node) + +This function is used when using zone-based storage. + +`clearDNSZone()` removes the entire zone for a given domain. + +The argument for the function is as follows: + - node: the nodehash of the fully-qualified domain in ENS for which to clear the zone. Node hashes are defined in (ENS EIP?) + +## Backwards compatibility +Not applicable. + +## Implementation +The reference implementation of the DNS resolver is at https://github.com/wealdtech/wealdtech-solidity/blob/master/contracts/ens/DNSResolver.sol + +## Test Cases +Test cases for the DNS resolver are at https://github.com/wealdtech/wealdtech-solidity/blob/master/test/ens/DNSResolver.js + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 12e9e91f15127e4433eaa00f95d17779b69a72d5 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 27 Jun 2018 11:58:57 +0100 Subject: [PATCH 2/7] Update and rename eip-draft_ens_dns.md to eip-1185.md --- EIPS/{eip-draft_ens_dns.md => eip-1185.md} | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) rename EIPS/{eip-draft_ens_dns.md => eip-1185.md} (99%) diff --git a/EIPS/eip-draft_ens_dns.md b/EIPS/eip-1185.md similarity index 99% rename from EIPS/eip-draft_ens_dns.md rename to EIPS/eip-1185.md index 0543ea4be3c570..b2ef428f57beb0 100644 --- a/EIPS/eip-draft_ens_dns.md +++ b/EIPS/eip-1185.md @@ -1,12 +1,14 @@ -eip: +--- +eip: 1185 title: Storage of DNS Records in ENS author: Jim McDonald status: Draft type: Standards Track category ERC created: 2018-06-26 -requires: #137 - +requires: 137 +--- + ## Abstract This EIP defines a resolver profile for ENS that provides features for storage and lookup of DNS records. This allows ENS to be used as a store of authoritative DNS information. From df95d69d78bbb5f9879e79b908f0fce57536c3e7 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 27 Jun 2018 11:59:08 +0100 Subject: [PATCH 3/7] Update eip-1185.md --- EIPS/eip-1185.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1185.md b/EIPS/eip-1185.md index b2ef428f57beb0..31adb06b6b7094 100644 --- a/EIPS/eip-1185.md +++ b/EIPS/eip-1185.md @@ -4,7 +4,7 @@ title: Storage of DNS Records in ENS author: Jim McDonald status: Draft type: Standards Track -category ERC +category: ERC created: 2018-06-26 requires: 137 --- From 0ebb70dd0b31fea71520f5d6d5360432b7d312e5 Mon Sep 17 00:00:00 2001 From: Jim McDonald Date: Sun, 14 Oct 2018 13:38:20 +0100 Subject: [PATCH 4/7] Clarify motivation and provide only a single interface for updating and obtaining records --- EIPS/eip-1185.md | 65 +++++++++++++----------------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) diff --git a/EIPS/eip-1185.md b/EIPS/eip-1185.md index 31adb06b6b7094..0511c11ac2ba27 100644 --- a/EIPS/eip-1185.md +++ b/EIPS/eip-1185.md @@ -7,43 +7,43 @@ type: Standards Track category: ERC created: 2018-06-26 requires: 137 +discussions-to: https://github.com/ethereum/EIPs/pull/1185 --- ## Abstract This EIP defines a resolver profile for ENS that provides features for storage and lookup of DNS records. This allows ENS to be used as a store of authoritative DNS information. ## Motivation -ENS is a perfect store for DNS records. It provides the distributed authority of DNS without conflating ownership and serving of information. With ENS, the owner of a domain has full control over their own DNS records. Separately, ENS has the ability (through smart contracts) for a domain's subdomains to be irrevocably assigned to another entity. +ENS is a highly desirable store for DNS information. It provides the distributed authority of DNS without conflating ownership and authoritative serving of information. With ENS, the owner of a domain has full control over their own DNS records. Also, ENS has the ability (through smart contracts) for a domain's subdomains to be irrevocably assigned to another entity. ## Specification The resolver profile to support DNS on ENS builds on the standalone resolver as defined in #137. -Traditionally, DNS is a zone-based system in that all of the records for a zone are kept together in the same file. This has the benefit of simplicity and atomicity of zone updates, but when transposed to ENS can result in significant gas costs for simple changes. As a result, the resolver provides the ability to store either zone-based or record-based DNS information for a given domain, each with their own set of functions for managing the information. +Traditionally, DNS is a zone-based system in that all of the records for a zone are kept together in the same file. This has the benefit of simplicity and atomicity of zone updates, but when transposed to ENS can result in significant gas costs for simple changes. As a result, the resolver works on the basis of record sets. A record set is uniquely defined by the tuple (domain, name, resource record type), for example the tuple (example.com, www.example.com, A) defines the record set of A records for the name www.example.com in the domain example.com. A record set can contain 0 or more values, for example if www.example.com has A records 1.2.3.4 and 5.6.7.8 then the aforementioned tuple will have two values. -The primary reason that a user might choose to use the zone-based functions is if the zone uses information that spans multiple records and requires strict ordering (for example DNSSEC with NSSEC/NSSEC3 records), so an unordered record-based storage system is not possible. If this is not a consideration then record-based storage is generally cheaper and more flexible. +The choice to work at the level of record sets rather than zones means that this specification cannot completely support some features of DNS, such as zone transfers and DNSSEC. It would be possible to build a different resolver profile that works at the zone level, however it would be very expensive to carry out updates and so is not considered further for this EIP. -A DNS zone is uniquely identified by the domain for which it contains records. A DNS record set is uniquely identified by the domain, label and resource record type. - -One of zone-based or record-based functions should be chosen for a given ENS domain. If both are used then results from a DNS resolver may be inconsistent. - -The DNS resolver interface consists of three functions to update DNS information and three functions to query DNS information. +The DNS resolver interface consists of two functions to set DNS information and two functions to query DNS information. ### setDNSRecords(bytes32 node, bytes data) -This function is used when using record-based storage. - `setDNSRecords()` sets, updates or clears 1 or more DNS records for a given node. The arguments for the function are as follows: - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 - - data: 1 or more DNS records in DNS wire format. + - data: 1 or more DNS records in DNS wire format. Any record that is supplied without a value will be cleared + +### clearDNSZone(bytes32 node) + +`clearDNSZone()` removes all DNS records for the domain. Although it is possible to clear records individually with `setDNSRecords()` as described above this requires the owner to know all of the records that have been set (as the resolver has no methods to iterate over the records for a given domain), and might require multiple transactions. `clearDNSZone()` removes all zone information in a single operation. -### dnsRecord(bytes32 node, bytes32 name, uint16 resource) +The arguments for the function is as follows: + - node: the nodehash of the fully-qualified domain in ENS for which to clear the records. Node hashes are defined in #137 -This function is used when using record-based storage. +### dnsRecords(bytes32 node, bytes32 name, uint16 resource) view returns (bytes) -`dnsRecord()` obtains the DNS records for a given node, name and resource. +`dnsRecords()` obtains the DNS records for a given node, name and resource. The arguments for the function are as follows: - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 @@ -52,11 +52,9 @@ The arguments for the function are as follows: The function returns all matching records in DNS wire format. If there are no records present the function will return nothing. -### hasDNSRecords(bytes32 node, bytes32 name) +### hasDNSRecords(bytes32 node, bytes32 name) view returns (bool) -This function is used when using record-based storage. - -`hasDNSRecords()` reports if there are any records for the provided name in the domain. This is needed by DNS resolvers when working with wildcard resources. +`hasDNSRecords()` reports if there are any records for the provided name in the domain. This is needed by DNS resolvers when working with wildcard resources as defined in https://tools.ietf.org/html/rfc4592 The arguments for the function are as follows: - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 @@ -64,42 +62,13 @@ The arguments for the function are as follows: The function returns `true` if there are any records for the provided node and name, otherwise `false`. -### setDNSZone(bytes32 node, bytes data) - -This function is used when using zone-based storage. - -`setDNSZone()` sets or updates the DNS zone file for a given domain. - -The arguments for the function are as follows: - - node: the nodehash of the fully-qualified domain in ENS for which to set the zone. Node hashes are defined in #137 - - data: the entire zone in DNS wire format - -### dnsZone(bytes32 node) - -This function is used when using zone-based storage. - -`dnsZone()` obtains the DNS zone file for a given domain. - -The argument for the function is as follows: - - node: the nodehash of the fully-qualified domain in ENS for which to set the zone. Node hashes are defined in #137 - -The function returns the entire zone in DNS wire format. If there is no zone present the function will return nothing. - -### clearDNSZone(bytes32 node) - -This function is used when using zone-based storage. - -`clearDNSZone()` removes the entire zone for a given domain. - -The argument for the function is as follows: - - node: the nodehash of the fully-qualified domain in ENS for which to clear the zone. Node hashes are defined in (ENS EIP?) - ## Backwards compatibility Not applicable. ## Implementation The reference implementation of the DNS resolver is at https://github.com/wealdtech/wealdtech-solidity/blob/master/contracts/ens/DNSResolver.sol +https://github.com/wealdtech/ethereal.git can be used to test the functionality of the resolver with the "dns set", "dns get" and "dns clear" commands. ## Test Cases Test cases for the DNS resolver are at https://github.com/wealdtech/wealdtech-solidity/blob/master/test/ens/DNSResolver.js From 78ad348bba3d4005e6aa6565324734ed5f761172 Mon Sep 17 00:00:00 2001 From: Jim McDonald Date: Mon, 15 Oct 2018 08:44:54 +0100 Subject: [PATCH 5/7] Add function signatures --- EIPS/eip-1185.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-1185.md b/EIPS/eip-1185.md index 0511c11ac2ba27..be44ca06e0519d 100644 --- a/EIPS/eip-1185.md +++ b/EIPS/eip-1185.md @@ -28,7 +28,7 @@ The DNS resolver interface consists of two functions to set DNS information and ### setDNSRecords(bytes32 node, bytes data) -`setDNSRecords()` sets, updates or clears 1 or more DNS records for a given node. +`setDNSRecords()` sets, updates or clears 1 or more DNS records for a given node. It has function signature `0x0af179d7`. The arguments for the function are as follows: - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 @@ -36,14 +36,16 @@ The arguments for the function are as follows: ### clearDNSZone(bytes32 node) -`clearDNSZone()` removes all DNS records for the domain. Although it is possible to clear records individually with `setDNSRecords()` as described above this requires the owner to know all of the records that have been set (as the resolver has no methods to iterate over the records for a given domain), and might require multiple transactions. `clearDNSZone()` removes all zone information in a single operation. +`clearDNSZone()` removes all DNS records for the domain. It has function signature `0xad5780af`. + +Although it is possible to clear records individually with `setDNSRecords()` as described above this requires the owner to know all of the records that have been set (as the resolver has no methods to iterate over the records for a given domain), and might require multiple transactions. `clearDNSZone()` removes all zone information in a single operation. The arguments for the function is as follows: - node: the nodehash of the fully-qualified domain in ENS for which to clear the records. Node hashes are defined in #137 ### dnsRecords(bytes32 node, bytes32 name, uint16 resource) view returns (bytes) -`dnsRecords()` obtains the DNS records for a given node, name and resource. +`dnsRecords()` obtains the DNS records for a given node, name and resource. It has function signature `0x2461e851`. The arguments for the function are as follows: - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 @@ -54,7 +56,9 @@ The function returns all matching records in DNS wire format. If there are no r ### hasDNSRecords(bytes32 node, bytes32 name) view returns (bool) -`hasDNSRecords()` reports if there are any records for the provided name in the domain. This is needed by DNS resolvers when working with wildcard resources as defined in https://tools.ietf.org/html/rfc4592 +`hasDNSRecords()` reports if there are any records for the provided name in the domain. It has function signature `0x4cbf6ba4`. + +This function is needed by DNS resolvers when working with wildcard resources as defined in https://tools.ietf.org/html/rfc4592 The arguments for the function are as follows: - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 From d4f26f36d322fe8e8d6331f434f832e3372c3a1f Mon Sep 17 00:00:00 2001 From: Jim McDonald Date: Mon, 15 Oct 2018 15:53:25 +0100 Subject: [PATCH 6/7] Fixes as per PR comments --- EIPS/eip-1185.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-1185.md b/EIPS/eip-1185.md index be44ca06e0519d..32bcc6780d5f0f 100644 --- a/EIPS/eip-1185.md +++ b/EIPS/eip-1185.md @@ -7,7 +7,7 @@ type: Standards Track category: ERC created: 2018-06-26 requires: 137 -discussions-to: https://github.com/ethereum/EIPs/pull/1185 +discussions-to: https://ethereum-magicians.org/t/eip1185-dns-resolver-profile-for-ens/1589 --- ## Abstract @@ -31,7 +31,7 @@ The DNS resolver interface consists of two functions to set DNS information and `setDNSRecords()` sets, updates or clears 1 or more DNS records for a given node. It has function signature `0x0af179d7`. The arguments for the function are as follows: - - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 + - node: the namehash of the fully-qualified domain in ENS for which to set the records. Namehashes are defined in #137 - data: 1 or more DNS records in DNS wire format. Any record that is supplied without a value will be cleared ### clearDNSZone(bytes32 node) @@ -41,14 +41,14 @@ The arguments for the function are as follows: Although it is possible to clear records individually with `setDNSRecords()` as described above this requires the owner to know all of the records that have been set (as the resolver has no methods to iterate over the records for a given domain), and might require multiple transactions. `clearDNSZone()` removes all zone information in a single operation. The arguments for the function is as follows: - - node: the nodehash of the fully-qualified domain in ENS for which to clear the records. Node hashes are defined in #137 + - node: the namehash of the fully-qualified domain in ENS for which to clear the records. Namehashes are defined in #137 ### dnsRecords(bytes32 node, bytes32 name, uint16 resource) view returns (bytes) `dnsRecords()` obtains the DNS records for a given node, name and resource. It has function signature `0x2461e851`. The arguments for the function are as follows: - - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 + - node: the namehash of the fully-qualified domain in ENS for which to set the records. Namehashes are defined in #137 - name: the `keccak256()` hash of the name of the record in DNS wire format. - resource: the resource record ID. Resource record IDs are defined in https://en.wikipedia.org/wiki/List\_of\_DNS\_record\_types @@ -61,7 +61,7 @@ The function returns all matching records in DNS wire format. If there are no r This function is needed by DNS resolvers when working with wildcard resources as defined in https://tools.ietf.org/html/rfc4592 The arguments for the function are as follows: - - node: the nodehash of the fully-qualified domain in ENS for which to set the records. Node hashes are defined in #137 + - node: the namehash of the fully-qualified domain in ENS for which to set the records. Namehashes are defined in #137 - name: the `keccak256()` hash of the name of the record in DNS wire format. The function returns `true` if there are any records for the provided node and name, otherwise `false`. From 532759ff1973f7189a71742b299f1a8a20c21b5a Mon Sep 17 00:00:00 2001 From: Jim McDonald Date: Tue, 16 Oct 2018 09:18:43 +0100 Subject: [PATCH 7/7] Clarify ordering of data in setDNSRecords --- EIPS/eip-1185.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-1185.md b/EIPS/eip-1185.md index 32bcc6780d5f0f..9d8bf26b954f6f 100644 --- a/EIPS/eip-1185.md +++ b/EIPS/eip-1185.md @@ -18,7 +18,7 @@ ENS is a highly desirable store for DNS information. It provides the distribute ## Specification -The resolver profile to support DNS on ENS builds on the standalone resolver as defined in #137. +The resolver profile to support DNS on ENS follows the resolver specification as defined in #137. Traditionally, DNS is a zone-based system in that all of the records for a zone are kept together in the same file. This has the benefit of simplicity and atomicity of zone updates, but when transposed to ENS can result in significant gas costs for simple changes. As a result, the resolver works on the basis of record sets. A record set is uniquely defined by the tuple (domain, name, resource record type), for example the tuple (example.com, www.example.com, A) defines the record set of A records for the name www.example.com in the domain example.com. A record set can contain 0 or more values, for example if www.example.com has A records 1.2.3.4 and 5.6.7.8 then the aforementioned tuple will have two values. @@ -32,7 +32,7 @@ The DNS resolver interface consists of two functions to set DNS information and The arguments for the function are as follows: - node: the namehash of the fully-qualified domain in ENS for which to set the records. Namehashes are defined in #137 - - data: 1 or more DNS records in DNS wire format. Any record that is supplied without a value will be cleared + - data: 1 or more DNS records in DNS wire format. Any record that is supplied without a value will be cleared. Note that all records in the same RRset should be contiguous within the data; if not then the later RRsets will overwrite the earlier one(s) ### clearDNSZone(bytes32 node)