Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial ENS Registrar Specification #162

Closed
maurelian opened this issue Oct 25, 2016 · 36 comments
Closed

Initial ENS Registrar Specification #162

maurelian opened this issue Oct 25, 2016 · 36 comments
Labels

Comments

@maurelian
Copy link
Contributor

maurelian commented Oct 25, 2016

Some of the parameters and mechanisms in this document are outdated with respect to the version deployed on the main net. The following version was last updated 2017-03-13, and mostly describe the first version of the regirstrar deployed to the main net on 2017-03-14. It is kept here for posterity. An updated version can be seen here. Please also refer to ReadTheDocs or natspec comments in the deployed code.

EIP: Draft 
Title: Initial ENS Hash Registrar
Author: J. Maurelian and Nick Johnson
Status: Draft
Type: Informational
Created: 2016-10-25

Contents

  • Abstract
  • Motivations
  • Specification
    • Initial restrictions
    • Name format for hash registration
    • Auctioning names
    • Deeds
    • Deployment and Upgrade process
    • Registrar Interface
  • Rationale
    • Not committing to a permanent registrar at the outset
    • Valid names >= 7 characters
    • Restricting TLD to .eth
    • Holding ether as collateral
  • Prior work

Abstract

This ERC describes the implementation of a registrar contract to govern the allocation of names in the Ethereum Name Service (ENS). For background, refer to EIP 137.

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.

- EIP 137

A well designed and governed registrar is essential to the success of the ENS described in EIP 137, but is described separately in this document as it is external to the core ENS protocol.

In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and "name squatting", however the best approach for mitigation is unclear. Thus an "initial" registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the .eth top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande's hash registrar implementation in order to facilitate discussion. His design mockups are also very helpful for understanding the flow

This Initial Registrar contract will be replaced with a permanent registrar contract. The Permanent Registrar will increase the available namespace, and incorporate lessons learned from the performance of the Initial Registrar. This upgrade is expected to take place within approximately 2 years of initial deployment.

Motivations

The following factors should be considered in order to optimize for adoption of the ENS, and good governance of the Initial Registrar's namespace.

Upgradability: The Initial Registrar should be safely upgradeable, so that knowledge gained during its deployment can be used to replace it with an improved and permanent registrar.

Effective allocation: Newly released namespaces often create a land grab situation, resulting in many potentially valuable names being purchased but unused, with the hope of re-selling at a profit. This reduces the availability of the most useful names, in turn decreasing the utility of the name service to end users.

Achieving an effective allocation may or may not require human intervention for dispute resolution and other forms of curation. The Initial Registrar should not aim to create to most effective possible allocation, but instead limit the cost of misallocation in the long term.

Security: The registrar will hold a balance of ether without an explicit limit. It must be designed securely.

Simplicity: The ENS specification itself emphasizes a separation of concerns, allowing the most essential element, the registry to be as simple as possible. The interim registrar in turn should be as simple as possible while still meeting its other design goals.

Adoption: Successful standards become more successful due to network effects. The registrar should consider what strategies will encourage the adoption of the ENS in general, and the namespace it controls in particular.

Specification

Initial restrictions

The Initial Registrar is expected to be in service for approximately two years, prior to upgrading. This should be sufficient time to learn, observe, and design an updated system.

During the initial two year period, the available name space will be restricted to the .eth TLD.

This restriction is not implemented by the registrar, but rather by the owner of the ENS root node who should not assign any nodes other than .eth to the Initial Registrar. The ENS's root node should be controlled by multiple parties using a multisig contract.

The Initial Registrar will also prohibit registration of names shorter than the minNameLength parameter. The value of minNameLength will be 7 initially. This value will be reducible by a call from owner of the ENS's root node.

Name format for hash registration

Names submitted to the initial registrar must be hashed using Ethereum's sha3 function. Note that the hashes submitted to the registrar are the hash of the subdomain label being registered, not the namehash as defined in EIP 137.

For example, in order to register abcdefg.eth, one should submit sha3('abcdefg'), not sha3('abcdefg', sha3('eth', 0)).

Auctioning names

The registrar will allocate the available names through a Vickrey auction:

A Vickrey auction is a type of sealed-bid auction. Bidders submit written bids without knowing the bid of the other people in the auction. The highest bidder wins but the price paid is the second-highest bid. This type of auction... gives bidders an incentive to bid their true value.

- Vickrey Auction, Wikipedia

The timeline of the auction will be implemented as follows:

  1. The hash of the desired name is submitted to the Initial Registrar, and bidding is opened on the hash.
  2. The auction will last 5 days, except for auctions started during the first 3 weeks after deployment of the Initial Registrar, which will last until the end of the 4th week.
  3. Bidders submit a payment of ether, along with sealed bids as a hash of sha3(bytes32 hash, address owner, uint value, bytes32 salt). The transaction can obfuscate the true bid value by sending a greater amount of ether.
  4. All bids must be received before the start of the final 48 hours of the auction, which is the reveal period. During this time, bidders must submit the true parameters of their sealed bid. As bids are revealed, ether payments are returned according to the schedule of "refund ratios" outlined in the table below.
  5. After the 48 hour reveal period has finished, the Initial Registrar's finalizeAuction function can be called, which then calls the ENS's setSubnodeOwner function, recording the winning bidder's address as the owner of the hash of the name.

Deeds

The Initial Registrar contract does not hold a balance itself. All ether sent to the Registrar will be held in separate deed contracts. Deeds are initially associated with a bidder and their sealed bid. After an auction is completed and a hash is registered, the deed for the winning bid is held in exchange for ownership of the hash.

After 1 year of registration, the owner of a hash may choose to relinquish ownership and have the value of the deed returned to them. A deed for an owned hash may also be transferred to another account by its owner.

Deeds for non-winning bid can be closed by various methods, at which time any ether held will either be returned to the bidder, burnt, or sent to someone else as a reward for actions which help the registrar.

The following table outlines what portion of the balance held in a deed contract will be returned upon closure, and to whom. The remaining balance will be burnt.

Reason for Deed closure Refund Recipient Refund Percentage
A valid non-winning bid is unsealed. Bidder 99.9%
An invalid bid is unsealed. Bidder 1%
A sealed bid is cancelled. 1 Canceler 0.5%
An registered hash is reported as invalid. 2 Reporter 10%
Notes:
  1. Bids which remain sealed for at least 12 weeks may be cancelled by anyone to collect a small reward.
  2. Since names are hashed before auctioning and registration, the Initial Registrar is unable to enforce character length restrictions independently. A reward is therefore provided for reporting invalid names.

Deployment and Upgrade process

The Initial Registrar requires the ENS's address as a contructor, and should be deployed after the ENS. The multisig account owning the root node in the ENS should then set the Initial Registrar's address as owner of the eth node.

The Initial Registrar is expected to be replaced by a Permanent Registrar approximately 2 years after deployment. The following process should be used for the upgrade:

  1. The Permanent Registrar contract will be deployed.
  2. The multisig account owning the root node in the ENS will assign ownership of the .eth node to the Permanent Registrar.
  3. Owners of hashes in the Initial Registrar will be responsible for registering their deeds to the Permanent Registrar. A couple options are considered here:
    1. Require owners to transfer their ownership prior to a cutoff date in order to maintain ownership and/or continue name resolution services.
    2. Have the Permanent Registrar query the Initial Registrar for ownership if it is lacking an entry.

Planned deactivation

In order to limit dependence on the Initial Registrar, new auctions will stop after 4 years, and all ether held in deeds after 8 years will become unreachable.

Registrar Interface

function startAuction(bytes32 _hash);

  • Starts an auction for an available hash. If the hash is already allocated, or there is an ongoing auction, startAuction will throw.

function startAuctions(bytes32[] _hashes);

  • Starts multiple auctions on an array of hashes. This enables someone to open up an auction for a number of dummy hashes when they are only really interested in bidding for one. This will increase the cost for an attacker to simply bid blindly on all new auctions. Dummy auctions that are open but not bid on are closed after a week.

function shaBid(bytes32 hash, address owner, uint value, bytes32 salt) constant returns (bytes32 sealedBid);

  • Takes the parameters of a bid, and returns the sealedBid hash value required to participate in the bidding for an auction. This obfuscates the parameters in order to mimic the mechanics of placing a bid in an envelope.

function newBid(bytes32 sealedBid);

  • Bids are sent by sending a message to the main contract with a sealedBid hash and an amount of ether. The hash contains information about the bid, including the bidded name hash, the bid value, and a random salt. Bids are not tied to any one auction until they are revealed. The value of the bid itself can be masqueraded by sending more than the value of your actual bid. This is followed by a 48h reveal period. Bids revealed after this period will be burned and the ether unrecoverable. Since this is an auction, it is expected that most public hashes, like known domains and common dictionary words, will have multiple bidders pushing the price up.

function unsealBid(bytes32 _hash, address _owner, uint _value, bytes32 _salt);

  • Once the bidding period is completed, there is a reveal period during with the properties of a bid are submitted to reveal them. The registrar hashes these properties using the shaBid() function above to verify that they match a pre-existing sealed bid. If the unsealedBid is the new best bid, the old best bid is returned to its bidder.

function cancelBid(bytes32 seal);

  • Cancels an unrevealed bid, forfeiting the funds.

function finalizeAuction(bytes32 _hash);

After the registration date has passed, this function can be called to finalize the auction, which then calls the ENS function setSubnodeOwner() updating the ENS record to set the winning bidder as owner of the node.

function transfer(bytes32 _hash, address newOwner);

  • Update the owner of the ENS node corresponding to the submitted hash to a new owner. This function must be callable only by the current owner.

function releaseDeed(bytes32 _hash);

  • After some time, the owner can release the property and get their ether back.

function invalidateName(string unhashedName);

  • Since registration is done on the hash of a name, the registrar itself cannot validate names. This function can be used to report a name which is 6 characters long or less. If it has been registered, the submitter will earn 10% of the deed value. We are purposefully handicapping the simplified registrar as a way to force it into being restructured in a few years.

function transferRegistrars(bytes32 _hash) onlyOwner(_hash);

  • Used during the upgrade process to a permanent registrar. If this registrar is no longer the owner of the its root node in the ENS, this function will transfers the deed to the current owner, which should be a new registrar. This function throws if this registrar still owns its root node.

Rationale

Starting with a temporary registrar

Anticipating and designing for all the potential issues of name allocation names is unlikely to succeed. This approach chooses not to be concerned with getting it perfect, but allows us to observe and learn with training wheels on, and implement improvements before expanding the available namespace to shorter names or another TLD.

Valid names >= 7 characters

Preserving the shortest, and often most valuable, domain names for the upgraded registrar provides the opportunity to implement processes for dispute resolution (assuming they are found to be necessary).

Restricting TLD to .eth

Choosing a single TLD helps to maximize network effects by focusing on one namespace.

A three letter TLD is a pattern made familiar by it's common usage in internet domain names. This familiarity significantly increases the potential of the ENS to be integrated into pre-existing DNS systems, and reserved as a special-use domain name. A recent precedent for this is the reservation of the .onion domain.

Holding ether as collateral

This approach is simpler than the familiar model of requiring owners to make recurring payments to retain ownership of a domain name. It also makes the initial registrar a revenue neutral service, and creates a new business model on Ethereum, by enabling owners to rent names as a service.

Prior work

This document borrows heavily from several sources:

  • EIP 137 outlines the initial implementation of the Registry Contract (ENS.sol) and associated Resolver contracts.
  • ERC 26 was the first ERC to propose a name service at the contract layer
  • @alexvandesande's current implementation of the HashRegistrar

Edits:

  • 2016-10-26 Added link Alex's design in abstract
  • 2016-11-01 change 'Planned deactivation' to h3'
  • 2017-03-13 Update timelines for bidding and reveal periods
@alexvandesande
Copy link

alexvandesande commented Oct 25, 2016

Thanks for writing this up @maurelian!

Another important thing that I would like to stress out:

Auctioning should not be considered as buying a perpetual right to the domain, and a big part of the reason we want it to be temporary is so that the community can come up with a fair process for the renewal for the name. The main rationale behind this decision is that names are a limited resource with unknown future usefulnnes and we want to reduce, as much as possible, the incentives for a one time land grab. There are some interesting options being considered for exactly how to do that, but the main idea is that once you own a name there should be a rational incentive for users to release them back to the open market, specially if they are not doing any useful work with it. I won't go into details as it would derail the purpose of this particular EIP.

Also, notice that there's no party benefiting in any way from this auctions. The purpose of auctioning isn't a scheme to raise funds to anyone, but to create opportunity costs of holding names.

@Arachnid
Copy link
Contributor

Good points. We should also emphasise that it's expected that any permanent registrar would provide a migration path for the vast majority of domain holders, but that there's no ironclad guarantee that every single domain bought on the temporary registrar will be able to migrate - one possible example being blatant phishing domains. There's also no guarantees that the pricing scheme of the eventual registrar will relate to the interim registrar's pricing.

@maurelian
Copy link
Contributor Author

I know it's not a short read, so questions are very welcome in the gitter chat room: https://gitter.im/ethereum/go-ethereum/name-registry

I also just put up a simple Truffle project to make it easy to deploy and interact with the registrar locally: https://github.com/maurelian/ens-registry-truffle

@rabbit
Copy link

rabbit commented Oct 26, 2016

Excellent work. Are there any concerns around invalid name reporters? I'm not entirely clear on how that works.

@simenfd
Copy link

simenfd commented Oct 26, 2016

Are full unicode character set allowed for this?

@maurelian
Copy link
Contributor Author

maurelian commented Oct 26, 2016

@rabbit Thanks for the question. By concern, do you mean that people might submit a false report?

The invalidateName() function code is here. To report a name invalid, it is submitted unhashed so that its length can be verified first. Then the name is hashed, and if it is registered it will be invalidated. Does that answer your question?

@Arachnid
Copy link
Contributor

Arachnid commented Oct 26, 2016

@simenfd Yes, though if the name isn't a valid output of Nameprep, chances are nothing will resolve it correctly. It's up to people registering domains to check that's the case; if you want to register .eth, you can do that.

@Smithgift
Copy link

In, re: unicode, wouldn't international characters make the seven-character minimum irrelevant? I can't find an example system for name-prep, but it appears that it will produce a much longer ASCII form of what may be only two Chinese characters. (Or even one?)

On that matter, I'm not sure what limiting system could be used such that it will make sense to users seeking to register international names.

@Arachnid
Copy link
Contributor

In, re: unicode, wouldn't international characters make the seven-character minimum irrelevant? I can't find an example system for name-prep, but it appears that it will produce a much longer ASCII form of what may be only two Chinese characters. (Or even one?)

It sounds like you're thinking of punycode. The name service doesn't use punycode; international domain names are represented directly as unicode, so a 2 character Chinese name will only be 2 characters long.

@JohnDorien1
Copy link

JohnDorien1 commented Nov 5, 2016

This reads like a remake of #26 , just ignoring all comments made on it. Very disappointing!

@maurelian
Copy link
Contributor Author

@JohnDorien1 I've only just seen your comment. I think that on the contrary, this spec is informed by the lack of agreement on #26, thus the iterative approach. It leaves room for improvement based on actual observation.

@clowestab
Copy link

I mentioned this on Gitter, but it may also be of interest to anyone reading this.

My company builds out web based applications on good domain names. As an economist, and a software engineer I wrote the following as an interest piece.

It may provide some useful context re allocation.

The economics of domain names.

@0xc1c4da
Copy link

0xc1c4da commented Jan 8, 2017

@rabbit raised a very good point in status-im/status-mobile#669 about dangerous unicode patterns in domain names, could the spec advise on how to deal with this?

situation is worse than I thought seems to be a series of contextual rules? not great...

@rabbit
Copy link

rabbit commented Jan 8, 2017

unfortunately from the ENS side, due to hashing, there wouldn't be a way to avoid that. limitations on all sides, apparently browser behaviors differ too. TIL.

for reference: https://en.wikipedia.org/wiki/Nameprep
there are IDN conversions that would lead to "xn--google.com" for example. so following nameprep is the correct way to go. tricky issue.

@Arachnid
Copy link
Contributor

Arachnid commented Jan 8, 2017

RE unicode vs punycode, resolvers should not do unicode encoding (which leads to names like xn--foobar.com, for instance), but rather look up the unicode name directly.

Use of nameprep is discussed in #137. We don't go into browser prohibitions on names there, but should doubtlessly write up a guide; my suggestion is to suggest resolves adopt the same system as mozilla.

@alexvandesande
Copy link

@rabbit @jarradh My opinion is that the ENS should be as flexible as possible in registering names but which names are accepted and how they are displayed should be left up to each client. So you could register 💩.eth, but that doesn't mean that Mist will accept emojis as valid domain names. Same for other clients.

@alexvandesande
Copy link

Contextual clues that firefox uses are actually a smart solution: I can see mist only accepting Unicode characters and characters from the user's system: i.e., only accept chinese characters if the user is using Mist in chinese, (or has visited that site before). The client can be smarter than the ENS contract

@Arachnid
Copy link
Contributor

That's more or less the case, but while you can vary about which names you outright reject, everyone has to agree on how names are normalised; otherwise, the same name typed into different user-agents may result in different hashes being looked up.

@0xc1c4da
Copy link

I agree, we need to come to an agreement on how to normalise, unicode characters like U+202E (right to left override) seem especially problematic. While other browsers have tackled this problem, they can rely on rendering punycode, where it doesn't seem so fitting in our case. The more I look at this problem the stickier it seems to get.

@Arachnid
Copy link
Contributor

No, punycode is an entirely separate step from normalisation; normalisation is accomplished using nameprep. Nameprep is specified in #137 as the canonical way to normalise names on ENS.

In addition, user agents should prohibit names containing code points <0x80 other than [a-z0-9.-].

@Arachnid
Copy link
Contributor

RFC5891 section 4 describes the steps a registrar should take to ensure validity of a name. I'm working through it and will update this EIP and 137.

@Arachnid
Copy link
Contributor

Arachnid commented Jan 12, 2017

Update: The official and most recent standard to follow is UTS #46, which specifies normalisation rules and prohibited characters. Implementations should use UTS 46 with transitional=false and useStd3ASCIIRules=true. For JS, this module provides the necessary functionality: https://www.npmjs.com/package/idna-uts46

I've updated #137's section on names accordingly.

@emansipater
Copy link

Realise it's too late for this round, but thoughts for a later round of ENS auctions: as a compliment to being able to hide the upper bound of a bid through sending more than the bid value, one should be able to hide the lower bound of a bid through revealing multiple submissions to have contained the same "bid ID" and owner address, thus co-funding a single bid in blinded parts. Example: I want to bid 100 ETH so I make ten submissions with 10 ETH attached to each, but with all having the same blinded ID, owner address, and bid value (of 100 ETH), just different salts. When all 3 are revealed the attached amounts are counted as co-funding the single 100 ETH bid whose ID, owner address, and value they share. IDs which are insufficiently funded by the end of an auction, or where amounts and owners do not match across all submissions of the same ID, are invalid. This would, of course, require adding an ID field to the sealed bid format and significantly reworking the contracts that implement the auction. Note that we can't just use the owner address as the ID because owner addresses are sometimes public and this would permit scattershot invalidation of any bids made by that owner.

@LefterisJP
Copy link
Contributor

@maurelian With the ENS registrar deployment imminent in the mainnet the following may be misleading:

The auction will last 7 days, except for auctions started during the first 3 weeks after deployment of the Initial Registrar, which will last until the end of the 4th week.

I was informed that on mainnet the auction/reveal phases will last 5 days and 48 hours.

Can you edit the EIP?

@chejazi
Copy link

chejazi commented Apr 28, 2017

Is there proper handling of case sensitivity? Ethereum.eth and ethereum.eth will have different hash values, but effectively represent the same domain.

Also, performing the SHA3 of just the name doesn't seem sufficient to guard the secrecy. Assuming 7char are the most desired, I only need to generate ~8 Billion strings to know which 7 char [a-z] domains are being bid on. The best approach would be to include a salt when calculating the hash.

@maurelian
Copy link
Contributor Author

maurelian commented Apr 28, 2017

@chejazi the case senitivity issue is addressed in Nick's Jan 12 comments above.

There is a salt in the bid hashes: https://github.com/ethereum/ens/blob/master/contracts/HashRegistrarSimplified.sol#L320

@maurelian
Copy link
Contributor Author

Realizing this spec needs an update to catch up with Registrar changes. I'd hope to do so early next week.

@veox
Copy link
Contributor

veox commented Apr 29, 2017

Minor clarification needed (highlighted), both here and in EIP137:

the owner of a node in the ENS registry is its registrar.

Proposed:

the owner of a node in the ENS registry is that node's registrar.


EDIT: Oh, I see the editor-needs-review tag now.

@veox
Copy link
Contributor

veox commented Apr 29, 2017

Also, @alexvandesande's design mockups, hosted on Invision, are inaccessible due to the service being over quota.

Could they be provided on a different service? Perhaps on IPFS also?..

@GriffGreen
Copy link

@Arachnid I was reading this and thought the current burn rate was 0.1% but it seems to be .5%??

@LefterisJP
Copy link
Contributor

@maurelian As @GriffGreen already pointed out in the EIP, the table for "A valid non-winning bid is unsealed." case is outdated. As can be seen in the code the Refund Percentage should be 99.5% returned and not 99.9%. We burn 0.5% of the user's bid and not 0.1%

@maurelian
Copy link
Contributor Author

@LefterisJP @GriffGreen OK, I've added this notice to the top of the EIP:

Some of the parameters and mechanisms in this document are outdated with respect to the version deployed on the main net. Until this notice is removed or updated, please refer to ReadTheDocs or natspec comments in the deployed code.

And I commit to revising this in the next 24 hours.

maurelian added a commit to maurelian/EIPs that referenced this issue May 11, 2017
@maurelian
Copy link
Contributor Author

First revision here:
https://github.com/maurelian/EIPs/blob/e784c0f050f574327eeea28e918c9426c1b3c5d2/EIPS/eip-ens-initial-registrar.md

All information there should be accurate to the main net deployment.

I also plan to add another table similar to the refund schedule, listing the various timelines and other constants used in the contract.

@jianchang653
Copy link

"In order to limit dependence on the Initial Registrar, new auctions will stop after 4 years, and all ether held in deeds after 8 years will become unreachable."
What does that mean?

@ali8889
Copy link

ali8889 commented Sep 19, 2018

Goood

@github-actions
Copy link

github-actions bot commented Jan 5, 2022

There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added the stale label Jan 5, 2022
shemnon added a commit to shemnon/EIPs that referenced this issue May 25, 2023
Restore the opcodes to 0x5c and 0x5d, as per execution layer meeting ethereum#162.
shemnon added a commit to shemnon/EIPs that referenced this issue May 25, 2023
Restore the opcodes to 0x5c and 0x5d, as per execution layer meeting ethereum#162.
shemnon added a commit to shemnon/EIPs that referenced this issue May 25, 2023
Restore the opcodes to 0x5c and 0x5d, as per execution layer meeting ethereum#162.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests