# ENS Documentation import { Button } from '../components/ui/Button' ## 🪲 Bug Bounty Program The ENS bug bounty program rewards anyone who finds a bug in covered ENS smart contracts and ENS Labs assets. This page provides a brief overview of the program which is operated by Immunefi and ENS Labs. [See the full program](https://immunefi.com/bug-bounty/ens) ### Bounties 💸 Reward sizes are guided by the rules below, but are in the end, determined at the sole discretion of the ENS Labs team. #### Smart Contracts * **Critical**: up to $250,000 USD * **High**: up to $150,000 USD * **Medium**: up to $100,000 USD #### Websites and Applications * **Critical**: up to $50,000 USD * **High**: up to $20,000 USD * **Medium**: up to $5,000 USD * **Low**: up to $1,000 USD The ENS Labs team reserves the right to adjust bounty amounts at any time in the future. ## 📝 Changelog This page contains a list of changes and events that happened to the ENS protocol & ecosystem. ### Dentity Announcement On August 21st, 2024 the ENS Labs team announced a new integration with Dentity, an independent identity provider that allows users to verify information and share it on their ENS profile.0 This integration leverages a draft ENSIP that allows for W3C Verifiable Credentials to be stored inside ENS profiles. ### ENSv2 Announcement On March 28th, 2024 the ENS Labs team announced our plans and roadmap for scaling ENS to the entire internet and beyond. This involves migrating .eth registrations to a brand new system, in addition to improving support for existing L2 solutions. You can read more [on our blog](https://blog.ens.domains/post/ensv2), [on X](https://twitter.com/ensdomains/status/1795440186513576318), and [the forums](https://discuss.ens.domains/t/technical-feedback-thread-for-ensv2/19233). ## FAQ ### Which wallets and dApps support ENS? ENS is supported by a wide range of wallets and dApps, some notable ones can be found on the [integrations page](https://ens.domains/). This page is currently under construction however a link to add yourself will be put here soon. ### Can I hold my name with one address, and point it at the other? Yes, you can hold your name with one address and point it at another. Simply visit the [ENS Manager App](https://ens.app/) and update the appropriate address record (by chain) for your name to point to the address you wish. ### Once I own a name, can I create my own subdomains? Yes. You can create whatever subdomains you wish and assign ownership of them to other people if you desire. You can even set up your own registrar for your domain. Some resolvers might provide even more advanced features, read more [about Resolvers](/resolvers/quickstart). ### Can I change the address my name points to after I've bought it? Yes, you can update the addresses and other resources pointed to by your name at any time. To update your name checkout the [ENS Manager App](https://ens.app/). ### ETH Registration #### Why are names registered as hashes? Hashes provide a fixed length identifier that can easily be passed around between contracts with fixed overhead and no issues passing around variable-length strings. Read more about [labelhash, namehash, and encodings](/resolution/names). #### What characters are supported? ENS names are generally encoded using UTS-46. This means there is partial support for Unicode characters, including emoji. However technically possible to register any name, names that are not valid UTS-46 will not be resolvable by most resolvers. Therefore it is generally recommended for apps that implement registration to limit the characters that can be registered to ensure a smooth experience. To read more about supported characters [name normalization](/resolution/names). #### What does it cost to register a .eth domain? Currently, registration costs are set at the following prices: * 5+ character .eth names: $5 in ETH per year. * 4 character .eth names: $160 in ETH per year. * 3 character .eth names: $640 in ETH per year. 3 and 4 character names have higher pricing to reflect the small number of these names available. To read more about the pricing structure of .eth names [read more about pricing](/registry/eth) #### How long can I register a name for? You can register a name for as long as you would like. There is no maximum registration duration. #### What happens if I forget to renew my name? If you forget to renew your name, it will be released back to the public pool of available names. Luckily the expiration process has a 90 day grace period. This means that once the name expires the original owner has 90 days to renew the name before it is released. After the grace period, the name is released for registration by anyone with a temporary premium which decreases over a 21 days period. The released name continues to resolve your ETH address until the new owner overwrites it. #### In what way could I lose access to my name? The .eth registrar is built to ensure once issued, a name cannot be revoked or taken away from its owner. Potential loss can occur if the owner loses access to their private key, or if the owner forgets to renew their name. ### Root Registry #### Who owns the ENS rootnode? What powers does it grant them? The ENS rootnode is currently owned by the ENS DAO. It used to be owned by the ENS Multi-sig, a group of keyholders from different parts of the ecosystem, however as of [EP4.10](/dao/proposals/4.10) the ownership has been transferred to the ENS DAO. Ownership of the rootnode grants the ability to do the following: * Control allocation and replacement of TLDs other than .eth - this is required to implement DNSSEC integration. * Enable and disable controllers for the .eth registrar, which affect registration and renewal policies for .eth names. * Update the pricing for .eth names. * Receive and manage registration revenue. #### Can I register a TLD of my own within ENS? Yes and No, We consider ENS to be part of the 'global namespace' in co-existence with DNS, and it is our priority to not pollute the namespace. ENS-specific TLDs are restricted to only '.eth' on Ethereum Mainnet, or .eth and .test on testnets. By default ENS allows users to [import their DNS name](/learn/dns) through the use of the [DNS Registrar](/registry/dns). Existing DNS TLDs can [reach out to us](mailto\:info@ens.domains) to take control of their TLD. ### What are the differences between ENS and other naming services such as Namecoin or Handshake? ENS complements and extends the usefulness of DNS with decentralised, trustworthy name resolution for web3 resources such as blockchain addresses and distributed content, while Namecoin and Handshake are efforts to replace all or part of DNS with a blockchain-based alternative. ### Governance Token #### Can I recover tokens accidentally sent to the wrong address? The answer depends on the address the token was sent to. If you accidentally sent the token to the token.ensdao.eth address (0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72) or the wallet.ensdao.eth address (0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7) then the tokens might be recoverable. Contact the [Meta-governance working group](/dao/stewards/) at the [ENS Forum](https://discuss.ens.domains) and explain the situation. Tokens can only be sent back to the address they were sent from, so if it was sent from an exchange, contact your exchange support to make sure the address can receive tokens. If the tokens were sent to the null address (0x000..) or an address with a typo, then the tokens are unrecoverable and there's nothing that anyone can do. If the tokens were sent to an exchange or a third party, then contact that third party for help. import { EmbedLink } from '../components/EmbedLink' ## Terminology This page contains a glossary of terms used in the ENS documentation. ### Name An ENS identifier such as 'alice.eth'. Names may consist of multiple parts, called labels, separated by dots. This also includes DNS names like `name.xyz`, or subnames like `sub.name.eth`. ### 2LD Second-level domain. This refers to a subname/subdomain of a top-level domain. For example, `name.eth` and `name.com` are both second-level names. A subname of a 2LD is a third-level domain or 3LD. ### Subname / Subdomain A child name like `sub.name.eth`, whose parent is `name.eth`. Also referred to as a "subdomain". Every name (except for the root node) has a parent. For example, `name.eth` is a subname of `eth`. ``` sub.name.eth ``` ### TLD Top-level domain. This refers to names like `eth`, `com`, `xyz` which lie at the "top" of the naming hierarchy. ``` .eth .com .xyz ``` ### Manager The account that may edit the records of a name. The Manager may be changed by the Owner. ### Label An individual component of a name, such as 'alice'. ### Labelhash The keccak256 hash of an individual label. ### Namehash The algorithm used to process an ENS name and return a cryptographic hash uniquely identifying that name. Namehash takes a name as input and produces a *node*. ### Node A cryptographic hash uniquely identifying a name. ### Owner The owner of a name is the entity referenced in the ENS registry's owner field. An owner may transfer ownership, set a resolver, and create or reassign subdomains. ### Record A piece of information that an ENS name "resolves" to (points to). The most common record is the ETH Address record, which determines what ETH 0x address an ENS name points to. ### Registration A registration is a registrar's record of a user's ownership of a name. This is distinct from the owner field in the Registry; registrations are maintained in the registrar contract and additionally store information on expiry date, fees paid, etc. #### Registrar A registrar is a contract responsible for allocating subdomains. Registrars can be configured at any level of ENS, and are pointed to by the owner field of the registry. #### Registry The core contract of ENS, the registry maintains a mapping from domain name (at any level - x, y.x, z.y.x etc) to owner, resolver, and time-to-live. All lookups start with the Registry. #### Expiry The date and time at which an ENS name expires. The implications of expiration depend on the type of name it is. When a .eth 2LD expires (and its grace period elapses), then you lose ownership of the name. When a wrapped subname expires, you may or may not lose ownership, depending on whether the name was emancipated. #### Grace Period This is a short window of time after an ENS .eth name expires, in which the owner can still renew and retain the name. Currently this window is 90 days. #### TTL Stands for "Time To Live". This is a field in the core registry that can be set alongside the resolver. It can be used as a hint for clients to decide how long to cache resolved data. ### DNS This is the Domain Name Service used by the internet to resolve addresses and other records from human-readable names. ENS aims to be fully complementary and compatible with DNS, and supports easy importing of DNS names via a special [DNSSEC](#dnssec) registrar. #### DNSSEC Stands for Domain Name System Security Extensions. When a particular DNS TLD supports DNSSEC, then the owners of names can cryptographically sign records. This allows ENS to support easy importing of DNS names into the ENS registry, as the owner of the DNS name can prove ownership with those signed records. ### Resolver A resolver is a contract that maps from name to the resource (e.g., cryptocurrency addresses, content hash, etc). Resolvers are pointed to by the resolver field of the registry. #### Wildcard Resolver This refers to a resolver that supports [ENSIP-10](/ensip/10). This scheme allows clients to resolve data for subnames that either don't have a resolver of their own, or subnames that may not even exist onchain at all. For offchain names, this is typically used in conjunction with [CCIP Read](#ccip-read). ### Public Resolver This is a standard resolver contract implementation written by ENS Labs. It supports all record types and anyone can use it. This is the default resolver used when registering a new name via the official manager app. ### Offchain This term is typically used with respect to the Ethereum Mainnet blockchain. If data is not posted to the chain via an actual Ethereum Mainnet transaction, then it is "offchain". ENS names can also be offchain. For example names can use a special resolver to resolve records for subnames that don't exist onchain in the Registry. This is also typically done with [CCIP Read](#ccip-read). #### CCIP Read The "Cross Chain Interoperability Protocol Read" specification, also known as [EIP-3668](https://eips.ethereum.org/EIPS/eip-3668), authored by Nick Johnson, is a specification that allows for secure and trustless offchain data retrieval. It allows for an Ethereum call to defer to an [offchain gateway](/resolvers/ccip-read#writing-a-gateway) and then securely verify the resulting data onchain. With respect to ENS, this is typically used for offchain subnames that don't exist in the core Registry. ### Primary Name The ENS name that you want a particular ETH account to be associated with. When set, it will be displayed instead of your 0x address on integrating websites/apps. This is also often referred to as the "reverse record". #### Reverse Node A node in the Registry that can be claimed for any Ethereum account. The name this node represents is `[addr].addr.reverse`, where `[addr]` is the Ethereum public address (lowercase, without the "0x"). These reverse nodes are typically used to set a [Primary Name](#primary-name) for an account. #### Reverse Record Usually, this is referring to the [Primary Name](#primary-name). Technically speaking, a [Reverse Node](#reverse-node) can have multiple records set on it, the same as any node. ### NameWrapper #### Wrapped Name The [ENS Name Wrapper](/wrapper/overview) is a contract for ENS that allows you to "wrap" any ENS name into a ERC-1155 NFT. This includes not only .eth 2LDs like `name.eth`, but also DNS names like `name.xyz`, or subnames like `sub.name.eth`. #### Fuse The technical term for a specific "permission" bit for a wrapped name. As the name implies, once that bit is flipped on, the fuse is burnt and cannot be unburnt (unless the name expires). #### Emancipated A name is considered emancipated if it's parent is unable to replace/delete it. This is typically used to describe trustless subnames. ### Subgraph An indexed collection of data using TheGraph protocol. In this documentation portal, "the subgraph" usually refers to the official ENS subgraph maintained by ENS Labs. This is a useful offchain service that allows clients to query for information about names or accounts. ## Name Wrapper Contract Details The Name Wrapper contract is deployed on these chains: * Mainnet: [wrapper.ens.eth](https://etherscan.io/address/0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401#code) * Sepolia: [wrapper.ens.eth](https://sepolia.etherscan.io/address/0x0635513f179D50A207757E05759CbD106d7dFcE8#code) ### Wrapping and Unwrapping When wrapping a .eth 2LD, you're effectively transferring the ERC-721 NFT ownership to the Name Wrapper contract, which will take over the [Manager](/terminology#manager) role for the name as well. You can do this by calling the [wrapETH2LD](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#wrapeth2ld) method. Or, you can directly transfer the ERC-721 NFT to the Name Wrapper contract. In return, the contract issues you an ERC-1155 NFT. ```solidity NameWrapper.wrapETH2LD(string label, address wrappedOwner, uint16 ownerControlledFuses, address resolver) // For example wrapETH2LD( "myname", // "myname.eth" but only the label 0x1234..., // The address you want to own the wrapped name 0, // The owner-controlled fuse bits OR'd together, that you want to burn 0x1234... // The address of the resolver you want to use ) ``` When wrapping any other ENS name, you transfer the Manager of the name to the Name Wrapper contract. You can do this by calling the [wrap](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#wrap) method. In return, the contract issues you an ERC-1155 NFT. ```solidity NameWrapper.wrap(bytes name, address wrappedOwner, address resolver) // For example wrapETH2LD( 0x03737562046e616d650365746800, // The DNS-encoded version of "sub.myname.eth" 0x1234..., // The address you want to own the wrapped name 0x1234... // The address of the resolver you want to use ) ``` As the owner of the wrapped name, you can unwrap at any time by calling either [unwrapETH2LD](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#unwrapeth2ld) or [unwrap](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#unwrap). You can do this as long as the permission to unwrap has not been revoked. ```solidity NameWrapper.unwrapETH2LD(bytes32 labelhash, address registrant, address controller) // For example unwrapETH2LD( 0x952f..., // "myname.eth" but only the labelhash: keccak256('myname') 0x1234..., // The address you want to own the unwrapped name 0x1234... // The address you want to be the manager of the unwrapped name ) NameWrapper.unwrap(bytes32 parentNode, bytes32 labelhash, address controller) // For example unwrap( 0x6cbc..., // The namehash of the parent node, e.g. "myname.eth" 0xfa1e..., // The labelhash of the child to unwrap, e.g. keccak256('sub') 0x1234... // The address you want to be the manager of the unwrapped name ) ``` ### Burning Fuses / Setting Expiry If you are wrapping an existing .eth 2LD, then you can pass in the owner-controlled fuses at that time, see the above [Wrapping and Unwrapping](#wrapping-and-unwrapping) section. If you are creating a new subname, and you want to burn fuses at the same time, see the below [Creating Subnames](#creating-subnames) section. For other existing wrapped names, you can burn fuses with either the `setFuses` or `setChildFuses` methods. The `setFuses` method is used for a name that you own, but you do not necessarily own the parent of. You have the ability to burn any [Owner-Controlled Fuses](/wrapper/fuses#owner-controlled-fuses) you want. Note that your name must first be [Emancipated](/wrapper/states#emancipated) in order for you to be able to burn any owner-controlled fuses. All .eth 2LDs are automatically emancipated upon wrapping. When burning owner-controlled fuses, at a minimum you must burn the **`CANNOT_UNWRAP`** fuse (if it has not already been burned). ```solidity NameWrapper.setFuses(bytes32 node, uint16 ownerControlledFuses) // For example setFuses( 0x6cbc..., // The namehash of the node, e.g. "myname.eth" 1 // The owner-controlled fuse bits OR'd together, that you want to burn ) ``` The `setChildFuses` method is used for a subname that you own the parent of. As long as the subname has not yet been [Emancipated](/wrapper/states#emancipated), you can burn whatever [Parent-Controlled Fuses](/wrapper/fuses#parent-controlled-fuses) and [Owner-Controlled Fuses](/wrapper/fuses#owner-controlled-fuses) you want. At the same time, you must set an expiry for those fuses, if one is not already set. Note that your name must first be [Locked](/wrapper/states#locked) in order for you to burn fuses on any subnames. If you are only burning parent-controlled fuses, then there are no further restrictions. However, if you are burning owner-controlled fuses, then you must at a minimum burn both **`PARENT_CANNOT_CONTROL`** and **`CANNOT_UNWRAP`** on the subname to lock it at the same time. ```solidity NameWrapper.setChildFuses(bytes32 parentNode, bytes32 labelhash, uint32 fuses, uint64 expiry) // For example setChildFuses( 0x6cbc..., // The namehash of the parent node, e.g. "myname.eth" 0xfa1e..., // The labelhash of the child, e.g. keccak256('sub') 65537, // The fuse bits OR'd together, that you want to burn 2021232060 // The expiry for the subname ) ``` ### Creating Subnames This is done very similarly to how unwrapped subnames are created. You call either `setSubnodeOwner` or `setSubnodeRecord` on the wrapper contract. When a name is wrapped, all subnames created will also be wrapped by default. You can also pass in the fuses and expiry at the same time, so that the subname will be created in the fuse/permission state that you want, without needing to perform an extra transaction. ```solidity NameWrapper.setSubnodeOwner(bytes32 parentNode, string label, address owner, uint32 fuses, uint64 expiry) // For example setSubnodeOwner( 0x6cbc..., // The namehash of the parent node, e.g. "myname.eth" "sub", // The label of the subname to create 0x1234..., // The address you want to be the owner of the new subname 65536, // The fuse bits OR'd together, that you want to burn 2021232060 // The expiry for the subname ) NameWrapper.setSubnodeRecord(bytes32 parentNode, string label, address owner, address resolver, uint64 ttl, uint32 fuses, uint64 expiry) // For example setSubnodeRecord( 0x6cbc..., // The namehash of the parent node, e.g. "myname.eth" "sub", // The label of the subname to create 0x1234..., // The address you want to be the owner of the new subname 0x5678..., // The address of the resolver to set for the new subname 0, // The TTL to set for the new subname 65536, // The fuse bits OR'd together, that you want to burn 2021232060 // The expiry for the subname ) ``` ### Approved Operators #### Full-Control Operator Batch Approvals Your wrapped name is an ERC-1155 NFT that supports the `setApprovalForAll` method. When you approve an address using this method, it will have **full control** over all wrapped ENS names that you own. This method is typically used by NFT marketplace contracts. #### Name-Specific Subname Renewal Manager Approvals The Name Wrapper also supports the ERC-721 `approve` method. This method is used to approve a single "Subname Renewal Manager" for a specific name. The "Renewal Manager" does not have full control over your wrapped name, it can only set / extend the expiry on subnames. Further, if you burn the **`CANNOT_APPROVE`** fuse on your name, then the approved renewal manager can no longer be changed. You can use this to "lock in" that contract, so that you can guarantee to all subname owners that renewals/extensions can always be done. This approved renewal manager will be reset if the wrapped NFT is burned or re-minted, which happens if you unwrap the name, or if an expired name gets re-registered. It will also be reset if the wrapped NFT is transferred, **unless** the **`CANNOT_APPROVE`** fuse is burned. #### Example - Subname Registrar Contract You can use these operator approval methods to setup a separate contract that can take certain actions on your behalf. One example is setting up a "subname registrar" to allow users to register/renew subnames. That subname registrar contract would act on your behalf and allow users to register subnames. To allow this, you would call `setApprovalForAll` to give that contract full control over your name (and thus the ability to create subnames). Then, to enable "unruggable renewals", you could call `approve` on that same contract (or a separate one specific to renewals if you wish) and burn **`CANNOT_APPROVE`** to lock in subname renewals for that contract. If you need to later on, you would still be able to revoke with `setApprovalForAll`. So the contract would lose full control over your name (and the ability to create new subnames), but it would still be able to perpetually renew/extend existing subnames. And you can do all of this **without** needing to send your wrapped NFT to that contract. ## Creating a Subname Registrar In the [Use Cases](/wrapper/usecases#sell-or-rent-subnames) section, we talked about the ability to stand up your own "registrar" to allow other people to register/claim subnames automatically. Maybe you want to give wrapped subnames out for free, or maybe you want to charge for them. Maybe you want to apply specific rules to the subnames, such as only allowing alphanumeric names. All of this is possible, and this article will break down what you need to do. It's recommended to first read the [Use Cases](/wrapper/usecases#sell-or-rent-subnames) section to get an overview of the decisions you'll need to make. ### Prerequisites This guide assumes that your parent name (such as `myname.eth`) is already wrapped. If you're not sure whether your name is wrapped, look at the "More" tab on the Manager app. If the name is unwrapped, it will say so, and it will show you a "Wrap Name" button. If you want to issue [Emancipated](/wrapper/states#emancipated) subnames, or subnames with [any other fuses](/wrapper/fuses) burned, then your parent name must first be [Locked](/wrapper/states#locked). You can do this on the Permissions tab in the ENS manager app. :::note With ENSv2 on the horizon, we recommend holding off on locking your name; locked names in the Name Wrapper will only be migratable to L1, so if you want to be able to issue trustless subnames on Namechain your best option is to wait until Namechain is live. ::: :::warning Locking your name (in other words revoking the permission to unwrap) is an **irreversible** change. After you lock the name, you will no longer be able to unwrap it. This is a security guarantee for the holders of all subnames. It ensures that the owner of the parent name cannot get around the security guarantees of the Name Wrapper. For development or testing purposes, it's best to do this on a Sepolia testnet name first. ::: ### Creating and Deploying your Registrar Contract In order to create a new subname, your contract should call either `setSubnodeOwner` or `setSubnodeRecord` on the [NameWrapper contract](/learn/deployments#deployments). Also pass in the fuses and expiry at the same time, as needed. ```solidity NameWrapper.setSubnodeOwner(bytes32 parentNode, string label, address owner, uint32 fuses, uint64 expiry) // For example setSubnodeOwner( 0x6cbc..., // The namehash of the parent node, e.g. "myname.eth" "sub", // The label of the subname to create 0x1234..., // The address you want to be the owner of the new subname 65536, // The fuse bits OR'd together, that you want to burn 2021232060 // The expiry for the subname ) NameWrapper.setSubnodeRecord(bytes32 parentNode, string label, address owner, address resolver, uint64 ttl, uint32 fuses, uint64 expiry) // For example setSubnodeRecord( 0x6cbc..., // The namehash of the parent node, e.g. "myname.eth" "sub", // The label of the subname to create 0x1234..., // The address you want to be the owner of the new subname 0x5678..., // The address of the resolver to set for the new subname 0, // The TTL to set for the new subname 65536, // The fuse bits OR'd together, that you want to burn 2021232060 // The expiry for the subname ) ``` Your public-facing registration function would typically take at *least* the parent node (namehash) and subname label as inputs, such as: ```solidity register(bytes32 parentNode, string calldata label) ``` Then under the hood, your contract will call `setSubnodeRecord` and fill in the rest of the parameters on behalf of the user: * owner: Typically the caller account, `msg.sender` * resolver: Typically the default public resolver, `resolver.eth` * ttl: 0 * fuses: Up to you and your goals. See the [Use Cases](/wrapper/usecases#sell-or-rent-subnames) section for a discussion on this. Typically 65536 for an enamcipated rental subname, or 327680 for an emancipated "forever" name. * expiry: Up to you and your goals. If you are renting subnames for a particular length of time, this expiry would reflect that. If you are allowing registration of "forever" names, then you can just set the expiry equal to the parent name's current expiry. Of course, if you want to give the registrant more power/convenience, you could allow some of those parameters to be passed in to your public register function as well. #### Setting Resolver Records If you want your subname registrar to set records on a subname in the same registration transaction, then the flow will be slightly different. In that case, perform these steps: * Call `setSubnodeOwner`, setting the *contract itself* (`address(this)`) as the owner of the subname, temporarily. This first step is needed for the default Public Resolver so that the contract has the authority to set records for the subname. * Call whatever [resolver methods](/resolvers/interacting) you need to. Perhaps these are records that you want to be pre-set on your subnames (such as an ETH address that the subname points to). Or perhaps these are records that you allow the registrant to pass in, so that they can register their subname and set whatever records they want all in one transaction. * Call `setSubnodeRecord`, but this time set the owner to the actual intended owner of the subname. This is the point at which you should set the appropriate fuses and expiry you want to, as well. In addition, you will need to make sure your contract follows the [ERC-1155 Token Receiver rules](https://eips.ethereum.org/EIPS/eip-1155#erc-1155-token-receiver). This means implementing the `onERC1155Received` and `onERC1155BatchReceived` methods, and signaling support for them in your ERC-165 `supportsInterface` method. OpenZeppelin has an easy abstract contract you can include for all this: [ERC1155Holder.sol](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/utils/ERC1155Holder.sol) #### Taking fees If you are setting up a "rental" registrar, then your registration function should require a certain amount of ETH to be sent in as well. Alternatively, you could choose to allow users to spend ERC-20 tokens instead. To accomplish that, you would typically call the ERC-20 method `transferFrom` on the token contract. This also means that the registrant would first need to approve your contract as a spender for that token, meaning they would need to execute a separate approval transaction first (either to approve unlimited spending, or to approve the specific number of tokens needed to register the subname). #### Reference Implementation Luckily, you don't need to start from scratch! The ENS Labs devs have created some example contracts you can start from: [https://github.com/ensdomains/ens-contracts/tree/feature/subdomain-registrar/contracts/subdomainregistrar](https://github.com/ensdomains/ens-contracts/tree/feature/subdomain-registrar/contracts/subdomainregistrar) These contracts include two different implementations: ##### Forever Subname Registrar This is a basic FIFS (First in first serve) registrar. The registration can take a fixed fee, or this fee can be set to 0 if you wish for subnames to be free. Names automatically are set to the parent's expiry can the fuse for `CAN_EXTEND_EXPIRY` will be burnt on registration so the user can extend their expiry if the parent also extends theirs. For a better UX, it is recommended that the parent sets their expiration as high as possible to allow their users to not have to think about renewing. ##### Rental Subname Registrar This is a basic FIFS (First in first serve) registrar. The key difference between this and the ForeverSubdomainRegistrar is that it does not auto-burn the `CAN_EXTEND_EXPIRY` fuse and instead exposes a `renew()` function that allows paid renewal. This registrar also needs to be paired with a rental-based pricing contract. For simplicity, the deployer can deploy this pricing contract and the UI can pass this address through to `setupDomain()` when a new user wants to setup a subname. ### Setting Everything Up Once you have a parent name ready and a subname registrar contract deployed, then you just need a few extra steps to set everything up: #### (If needed) Call setupDomain on your contract This will only apply to you if you have a specific `setupDomain` method or something similar on your contract, such as the [reference implementation](/wrapper/creating-subname-registrar#reference-implementation) contracts do. Calling this method will "enable" a specific parent name in your subname registrar. It can also allow you to set or update the pricing terms or beneficiary account, if needed. #### Approve your contract Call `setApprovalForAll` on the NameWrapper contract, approving your subname registrar contract as an operator for any names you own. This allows you to keep ownership of the parent name, and just delegate subname creation to your contract. #### (If needed) Approve token spending If your registrar contract takes ERC-20 tokens as a registration fee, then a potential registrant will need to approve your contract as a spender first. #### Register a subname Finally, the registrant will call your public registration method. Upon transaction success, they will own the wrapped name (ERC-1155 NFT) with whatever fuse/expiry guarantees that you setup in your registrar. If you are allowing "forever" subnames to be registered (meaning that you've burned the `CAN_EXTEND_EXPIRY` fuse on the subnames), then the registrant can extend their own expiry at any time. Note that a subname's expiry can be set up to a maximum of whatever the parent name's expiry is. And that's it! import { Card } from '../../components/ui/Card' ## Name Wrapper Expiry In order to burn any fuses on a name, you must also set an **expiry** on it. This expiry determines how long any burned fuses are active for, and may also determine whether the name itself has expired. If the name is a .eth 2LD, then the expiry will automatically be set to the same expiry in the .eth Registrar. But for all other names, the parent can choose what expiry to set for a child name. ### Max Expiry for Subnames By default, the expiry for a name can only be set by the parent, and can only be increased, not decreased. The maximum value for the expiry of a name is the expiry of its parent name. For example, say a name expires in 5 years. The owner of the name can then set the expiry of its subnames to a maximum of 5 years as well. But the parent could also choose to set the expiry to something less. Let's say the parent sets the expiry of one of its subnames to 2 years. Then in turn, the owner of the subname can set the expiry of its own subnames up to a maximum of 2 years, but it could also set it to something less, like 1 year. Expiry Diagram The parent can set a different expiry for different subnames too, just as it can burn different fuses for different subnames. ### Renewals When a wrapped .eth second-level name (like `name.eth`) is renewed, that new expiry is automatically set in the Name Wrapper as well as in the .eth Registrar. However, the expiry for any other .eth names (like `sub.name.eth`) will not be automatically extended when the parent expiry is extended. The parent can extend the expiry for an existing subname at any time, even if the subname has been emancipated. The parent can also choose to approve a separate contract to allow the expiry for subnames to be extended by the subname owner or other accounts. That is basically how .eth second-level names work: Since the `eth` node is locked in the registrar contract and has the Name Wrapper (which exposes a renew method) approved as a controller, .eth second-level names can be directly renewed by their owners. The parent can further lock this approved contract in by burning the **`CANNOT_APPROVE`** fuse. There is also a special parent-controlled fuse called **`CAN_EXTEND_EXPIRY`**. If the parent burns this fuse on a subname, then the owner of that subname (or any approved controller) can also extend the expiry. So, if you are running a subname registrar and you want to enable "unruggable renewals", you can use one of the above options (or both). ### Special Cases for .eth 2LDs For .eth second-level names, the end of the name's grace period (from the .eth Registrar) is used for the expiry inside of the Name Wrapper. So if the name's expiration date in the Registrar is January 1st, then the expiry in the Name Wrapper will reflect that date *plus* the grace period (currently 90 days, so approximately April 1st, depending on the year). When the name's expiration date (from the .eth Registrar) has been reached, and the name is now in the grace period, all Name Wrapper operations on the name will be restricted. The owner will *not* yet lose ownership of the name, but they will also not be able to unwrap or update the name until it has been renewed. ### Expiry Implications When a name is merely **Wrapped** but not **Emancipated** or **Locked**, parent-controlled fuses can still be burned. This means that the parent can burn a custom fuse for a limited amount of time. When the expiry (end of grace period for .eth 2LDs) is reached, all fuses will be reset, but the name will otherwise be unaffected. When a name is **Emancipated** or **Locked**, the expiry has an important additional effect. In this scenario, when the expiry (end of grace period for .eth 2LDs) has been reached, **the name itself will expire**, and the owner **loses ownership** of the name. ## Name Wrapper Fuses A "fuse" is a permission or perk that can be granted/revoked on a name. As the name implies, once the fuse is "burned", it cannot be unburned. Fuses will only reset when the **expiry** is reached. In the ENS Manager UI, this is available in the "Permissions" section of the name. By **wrapped expiry**, we mean that for .eth second-level names (like `name.eth`), this is the end of the 90-day grace period, the time at which the .eth 2LD is truly released. For all other names (such as subnames), there is no grace period, so the expiry is just the expiration date for that specific subname. For example, by default when you wrap a name, you can transfer that NFT around freely, just as you can with other NFTs. However, if the **`CANNOT_TRANSFER`** fuse is burned, then the NFT becomes non-transferrable. In the ENS Manager UI, you would do this by revoking the "Can send this name" permission. In order to burn fuses on a name, the parent name must be **Locked** (meaning, you cannot unwrap the name). The reason is, if the parent name was not locked, then the owner of the parent name could simply get around the constraints of the Name Wrapper by unwrapping the name, and replacing/revoking subnames against the core ENS Registry. There are parent-controlled and owner-controlled fuses: ### Parent-Controlled Fuses Only the owner of the parent name can burn one of these fuses on a name. These can generally be thought of as "perks" that can be granted to a name, though they can be used in other ways. | Fuse name | Description | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **`PARENT_CANNOT_CONTROL`** | Allows a parent owner to **Emancipate** a child name. After this is burned, the parent will no longer be able to burn any further fuses, and will no longer be able to replace/delete the child name. This fuse must be burned in order for any owner-controlled fuses to be burned on the name. | | **`IS_DOT_ETH`** | This fuse cannot be burned by users of the Name Wrapper, it is only set internally when a .eth 2LD is wrapped. | | **`CAN_EXTEND_EXPIRY`** | The owner of the child name will be able to extend their own expiry. Normally, only the parent owner can extend the expiry of a child name. See the [Expiry](/wrapper/expiry) section for more information. | | **Custom Fuses** | There are 13 other parent-controlled fuses that are not reserved, and can be used in any custom way you want! | ### Owner-Controlled Fuses Either the owner of the name or the owner of the parent name can burn one of these fuses. These can generally be thought of as "permissions" that can be revoked on a name, though they can be used in other ways. | Fuse name | Description | | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **`CANNOT_UNWRAP`** | The name will now be **Locked**, and can no longer be unwrapped. This fuse must be burned in order for any other owner-controlled fuses to be burned on the name. | | **`CANNOT_BURN_FUSES`** | No further fuses can be burned on the name. | | **`CANNOT_TRANSFER`** | The name (wrapped NFT) can no longer be transferred. | | **`CANNOT_SET_RESOLVER`** | The resolver contract for the name can no longer be updated. | | **`CANNOT_SET_TTL`** | The TTL for the name can no longer be updated. | | **`CANNOT_CREATE_SUBDOMAIN`** | New subdomains can no longer be created. | | **`CANNOT_APPROVE`** | The approved "subname renewal manager" for the name can no longer be updated. See the [Approved Operators](#approved-operators) section for more information. | | **Custom Fuses** | There are 9 other owner-controlled fuses that are not reserved, and can be used in any custom way you want! | ### The Emancipated and Locked States This is also covered in the [Wrapped States](/wrapper/states) section, but here is a quick recap: All .eth second-level names (like `name.eth`) are automatically placed into the Emancipated state when wrapped. **Emancipated** means that the parent no longer has control over the child name. It can no longer burn any fuses or replace the subname, up until the expiry. A name is Emancipated when the parent burns the **`PARENT_CANNOT_CONTROL`** (PCC) fuse. The parent must first be in the Locked state to be able to do this. **Locked** means that the name cannot be unwrapped. This provides assurance to subnames that the parent owner cannot unwrap and then, for example, start replacing subnames directly against the registry. An Emancipated name is Locked when the **`CANNOT_UNWRAP`** (CU) fuse is burned. Think of the special PCC / CU fuses recursively: * To burn owner-controlled or subname fuses, CU must be burned. * To burn CU, PCC must be burned. * Only the parent can burn PCC on the child name, and only if CU is first burned on the parent. * Only the grandparent can burn PCC on the parent name, and only if CU is first burned on the grandparent. * And so on... Follow that chain up until you hit a .eth second-level name like `name.eth`, since .eth second-level names will have PCC automatically burned when wrapping. The parent `eth` node is already in the Locked state. A parent name can burn all the fuses it needs to on a child name in one transaction. This can be done when the subname is created, or on an existing subname that has not yet been Emancipated. ### DNS Domains and Fuses Currently, only .eth names support fuses, because only the `eth` node is onchain native and completely locked beyond anyone's control. Technically speaking, the owner of a DNS TLD has the ability to burn fuses on that TLD in the Name Wrapper, and set it to the "Locked" state. And then from there, all subnames under that DNS TLD *will* be able to use fuses. The DNS TLD owner would need to: * Request the Controller of that TLD from the ENS DAO * Wrap the TLD node in the Name Wrapper * Burn the **`PARENT_CANNOT_CONTROL`** and **`CANNOT_UNWRAP`** fuses on the wrapped TLD to lock it However, this still does not have all the immutable guarantees that .eth names do. This is because for DNS names, the "source of truth" always lies not in the Ethereum network, but in the DNS network, and the DNS root zone governed by ICANN stakeholders. So even if the DNS TLD owner "Locks" that TLD in the ENS Name Wrapper, if that TLD were to ever change ownership on the DNS side, then (per the [ENS DAO Constitution](https://docs.ens.domains/v/governance/ens-dao-constitution#iv.-ens-integrates-with-the-global-namespace)) the new owner would be able to override control of that TLD on the ENS side, unwrap it, and replace/revoke all 2LDs. This is just something to keep in mind for wrapped DNS domains. Even if wrapped DNS domains do not support fuses, you can still use them as ERC-1155 NFTs. They will still have their own NFT metadata and show up in your wallet, with whatever avatar you have set, etc. They just won't have all the extra functionality that comes with the fuse/permission system. import { Card } from '../../components/ui/Card' ## Name Wrapper Overview :::note Are you looking for user-facing guides on how to interact with the Name Wrapper in the ENS Manager App? If so, see here instead: [Name Wrapper Guides](https://support.ens.domains/en/collections/4194784-name-wrapper-guides) :::