ENS Logo

Name Wrapper Use-Cases

Lock the resolved records for a name

By default, newly registered names will use the Public Resolver, which just allows the current manager/controller of the name to update any records.

However, in some cases perhaps you want to make sure that a name resolves to specific records and never changes. You can accomplish this with the CANNOT_SET_RESOLVER fuse.

Say you own mycoolcontract.eth representing a smart contract. You can use ENS subnames to refer to specific versions of that contract, like 1.mycoolcontract.eth. And perhaps you want those versioned subnames to always point to:

  • The ETH address of that immutable contract
  • The ABI for that contract
  • The contenthash for some versioned documentation page
  • etc.

One way to do this is just to make sure the name is Locked, all the records are set correctly, and then transfer the owner to some burn address so it can never be updated again.

But of course this isn't ideal, because maybe there are some records that you do want to update in the future. Or maybe you still want to keep ownership of that subname for other reasons.

Instead of essentially burning the name, you could create a custom resolver that locks in certain records forever. Then:

  1. Set the resolver of that name to your custom contract
  2. Set the records however you want and lock them into the resolver
  3. Burn these fuses on the name:
    • PARENT_CANNOT_CONTROL | CANNOT_UNWRAP | CANNOT_SET_RESOLVER

Now you can still keep ownership and even some limited management power over the name, while still guaranteeing that the ETH address, ABI, and whatever other records are completely immutable, as long as the expiry is set appropriately.

Issue subdomains as tickets to an event

Maybe you have mycoolevent.eth and you want to issue tickets like 1.ticket.2023.mycoolevent.eth.

If you want, you can choose to not Emancipate those subnames, but still burn some custom parent-controlled fuses. Those fuses might:

  • Indicate what "tier" their event ticket is
    • Maybe they can upgrade their ticket to a higher tier, which would burn some additional fuses
  • Allow them access to the express line or some VIP room
    • Maybe even automatically via some smart door

When you burn those fuses, perhaps you also set the expiry to the day after the event ends.

Or, maybe you want your attendees to be able to keep their subnames as a souvenir or proof-of-attendance!

If so, then instead of letting the names expire at the end of the event, you could extend the expiry and burn some additional fuses to allow the attendees to keep them forever! In that case you might want to burn these fuses:

  • CAN_EXTEND_EXPIRY | PARENT_CANNOT_CONTROL

If you want those tickets to be non-transferrable (soulbound to the address that attended), then burn these fuses:

  • CAN_EXTEND_EXPIRY | PARENT_CANNOT_CONTROL | CANNOT_UNWRAP | CANNOT_TRANSFER

Sell or rent subnames

I want to sell / rent out subnames!

Say you own the wrapped name verypopularname.eth. Obviously you can just manually create wrapped subnames like my.verypopularname.eth and then sell them on an NFT marketplace. But that sure doesn't scale well.

To accomplish this, you will want to create a subname registrar. This is a contract that will handle all the registration / renewal for you, and then users will be able to interact with that contract in order to register their own subnames.

In fact, this is exactly how .eth 2LDs are registered. The owner of the eth TLD (the NFT contract) delegates registration / renewal to the ETHRegistrarController contract. It is acting as a subname registrar for the name eth.

Your contract would expose a register method that anyone can call. Under the hood it will use the setSubnodeOwner or setSubnodeRecord methods to create subnames, passing in the fuses and expiry you want to set.

What fuses should I burn???

First, note that if you want to burn any fuses on subnames, then your name must be Locked (meaning CANNOT_UNWRAP is burned).

Assuming that you want your subnames to be "unruggable", such that you cannot replace / revoke them, then you will want to burn PARENT_CANNOT_CONTROL on the subnames. This will place them in the Emancipated state upon registration.

If you want to sell "forever" subnames, where users register once and can then keep them for as long as they wish, then you can consider burning the CAN_EXTEND_EXPIRY fuse.

This will allow the subname owner to extend their own expiry whenever they want. The max expiry is the expiry of the parent name, but the .eth Registrar allows anyone to renew/extend a .eth 2LD as well.

If you just want to rent subnames, then do not burn CAN_EXTEND_EXPIRY. Instead, you could include a renew method on your contract that users can call for another fee.

If you want to enable "unruggable renewals" for your registrar, to guarantee that users will always be able to renew, then you can call approve on the Name Wrapper and approve your registrar contract as the "subname renewal manager" for your name.

Then, burn the CANNOT_APPROVE fuse on your name, to guarantee that you can never revoke that contract for subname renewals. See the Approved Operators section above for more info.

If you want to impose other restrictions on your registered subnames, then you can burn the CANNOT_UNWRAP fuse to Lock the subname, and also burn whatever other fuses you want.

For example, if you want to prevent owners of your subnames (like my.verypopularname.eth from creating their own subnames (like buy.my.verypopularname.eth), then you would burn CANNOT_UNWRAP and CANNOT_CREATE_SUBDOMAIN.

To recap on fuses...

  • Sell permanent names:
    • CAN_EXTEND_EXPIRY | PARENT_CANNOT_CONTROL
  • Sell permanent names, but prevent them from creating their own subnames:
    • CAN_EXTEND_EXPIRY | PARENT_CANNOT_CONTROL | CANNOT_UNWRAP | CANNOT_CREATE_SUBDOMAIN
  • Rent out names:
    • PARENT_CANNOT_CONTROL
  • Rent out names, but prevent them from transferring or reselling them:
    • PARENT_CANNOT_CONTROL | CANNOT_UNWRAP | CANNOT_TRANSFER

And so on, it's up to you. You can also burn whatever custom parent-controlled or owner-controlled fuses you want to.

Can I customize my own rules and fees?

Yes! It's your registrar contract, so you can impose whatever rules and fees you want.

For example, the .eth Registrar imposes a 3-character minimum on all names, as well as a custom fee structure and a temporary premium auction upon expiration.

By default there is no character limit on subnames, but your contract could have its own rules and fee structure or whatever you want. For example, you can:

  • Allow or disallow specific addresses from registering / renewing
  • Only allow registration based on some custom criteria like holding a specific NFT
  • Custom length restrictions like only 3+ characters or < 100 characters
  • Only allow names with characters [a-z0-9] and nothing else
  • Use a custom fee structure based on:
    • The length of the name
    • The specific characters that are in the name, like emojis
    • A pre-curated list of "good" names like people's first names
  • And whatever other rules you want.

More information

See this page for a step-by-step guide on creating and setting up your own subname registrar: Creating a Subname Registrar

There is even a set of reference implementation contracts you can use as a starting base!

Give subnames out to NFT holders

I want to give subnames out to all of my DAO members / NFT holders!

Say you own the wrapped name mycoolnft.eth, representing a popular NFT project you created. You want to distribute subnames like 6529.mycoolnft.eth to all holders.

One option is to just bulk create the subnames and drop the wrapped NFTs into their wallets. This might be good at least as an initial drop, because then the holders don't need to interact with any contract or spend any gas, you're doing that for them!

To create the subnames, you'd use the setSubnodeOwner or setSubnodeRecord methods.

You must also decide:

How much control over the subnames do you want to relinquish?

Do you want to be able to revoke subnames? Or do you want them to be completely outside your control?

One thing to consider is whether you want the current holder of your NFT to always be able to claim/reclaim the corresponding ENS subname. If so, then you will not want to Emancipate those subnames (in other words, do not burn PARENT_CANNOT_CONTROL).

If the subname is Emancipated, then the NFT holder could sell/transfer the NFT but keep the subname (up until the expiry).

To make it easy for anyone to claim/reclaim a subname after your initial drop, you can set up a contract for this.

Setting up a subname claim contract

The claim method of your contract could:

  1. Call ownerOf or balanceOf on your NFT contract to get or verify the current owner of the NFT
  2. Call ownerOf or balanceOf on the ENS Name Wrapper contract to get or verify the current owner of the wrapped subname
    • If both owner addresses are the same, just return, nothing to do
  3. Call setSubnodeOwner or setSubnodeRecord on the ENS Name Wrapper:
    • owner: The current owner of the NFT
    • fuses: What fuses you want to burn (if any) on that subname. If you burn any fuses, you must also set an expiry.
    • expiry: When the subname will expire.

Then, to give that contract access to create subnames on your behalf, you would call setApprovalForAll on the Name Wrapper to approve your contract as an operator.

Now, even if the NFT gets sold / transferred, the new owner will be able to claim their mycoolnft.eth subname at any time.

In addition, if you expand your NFT collection in the future and there are new owners, then those new owners would be able to claim their subnames as well.

If you are creating a new NFT contract, you could even bake this functionality directly into the NFT contract too, instead of needing a separate contract! By doing this, you wouldn't need a separate claim method either, your NFT contract would just automatically transfer the wrapped ENS subname whenever the NFT itself gets transferred!

Giving your subname owners perks

If you decide to not Emancipate the subnames that you issue, you will still be able to burn any Parent-Controlled Fuses. There are 13 unreserved parent-controlled fuses that you can use however you wish!

For example, perhaps you want to grant on-chain "perks" or "roles" to certain holders. You would call setChildFuses on the Name Wrapper and pass in the fuses you want to burn, and the expiry.

This means that those "perks" or "roles" can also be time-boxed if you want. Maybe a perk expires in 1 week or something, up to you.

There is also the reserved CAN_EXTEND_EXPIRY parent-controlled fuse. If you burn this, then the subname owner will be able to extend their own expiry whenever they want.

Contributors
Last Modified
4 months ago