A Comprehensive Guide to the Ethereum Name Service (ENS) System

·

The Ethereum Name Service (ENS) is an open and extensible naming system built on the Ethereum blockchain. It serves as the primary naming protocol within the ecosystem, transforming complex hexadecimal addresses into human-readable names like vitalik.eth. This system enables users to interact with blockchain addresses using familiar, memorable identifiers rather than long strings of characters.

How ENS Works: Core Architecture

ENS operates through a combination of smart contracts that work together to resolve names to their corresponding resources. The system consists of two primary components: the Registry and Resolvers.

The Registry Contract

The Registry is the fundamental core of the ENS system and serves as the starting point for all ENS queries. This contract maintains three critical pieces of information for each domain:

  1. The domain owner (owner)
  2. The domain's resolver contract (resolver)
  3. The time-to-live value for record caching (TTL)

Domain owners can grant modification permissions to operators who can manage domains on their behalf. The Registry's structure is implemented through the following Solidity code:

struct Record {
 address owner;
 address resolver;
 uint64 ttl;
}
mapping(bytes32 => Record) records;
mapping(address => mapping(address => bool)) operators;

Resolver Contracts

Resolvers are smart contracts that perform the actual domain resolution process. Any contract that complies with ENS standards can serve as a resolver, allowing users to add custom resolvable content for their domains. Currently, resolvers support various record types including:

The complete specification for resolver implementations can be found in the ENS Improvement Proposals (ENSIP) documentation.

The Domain Resolution Process

When an application needs to resolve an ENS name to its corresponding resource, it follows a specific workflow:

  1. The application queries the Registry's resolver function to obtain the address of the resolver contract for the specific domain
  2. The application then calls the appropriate function on the resolver contract to retrieve the desired information

The Registry's resolver function appears as follows:

function resolver(bytes32 node) public view virtual override returns (address) {
 return records[node].resolver;
}

The node parameter represents the domain's unique identifier within the Registry contract, known as the namehash.

Understanding Namehashing

Namehashing is a process that converts human-readable domain names into fixed-length hashes that can be efficiently processed by smart contracts. The process involves two key steps:

  1. Name Normalization: ENS supports non-ASCII characters through UTS46 encoding, which converts all domains to a case-insensitive ASCII representation. This means FOO.eth and foo.eth are considered identical within the ENS system.
  2. Hierarchical Hashing: The namehash algorithm preserves domain hierarchy, allowing parent domains to manage their subdomains. For example, wallet.eth can control vitalik.wallet.eth because their namehashes reflect this relationship.

The Registry contract implements hierarchical management through the setSubnodeOwner function:

function setSubnodeOwner(
 bytes32 node,
 bytes32 label,
 address owner
) public virtual override authorised(node) returns (bytes32) {
 bytes32 subnode = keccak256(abi.encodePacked(node, label));
 _setOwner(subnode, owner);
 emit NewOwner(node, label, owner);
 return subnode;
}

In this function, the label parameter represents the keccak hash of the subdomain name. For vitalik.wallet.eth, the label would be the keccak hash of "vitalik" while the node parameter would be the namehash of wallet.eth.

Address Resolution Mechanism

Once an application obtains the resolver address from the Registry, it calls the resolver's addr function to retrieve the actual address associated with an ENS name. The basic implementation for Ethereum address resolution appears as follows:

uint256 private constant COIN_TYPE_ETH = 60;
mapping(uint64 => mapping(bytes32 => mapping(uint256 => bytes))) versionable_addresses;

function addr(bytes32 node) public view virtual override returns (address payable) {
 bytes memory a = addr(node, COIN_TYPE_ETH);
 if (a.length == 0) {
 return payable(0);
 }
 return bytesToAddress(a);
}

function addr(bytes32 node, uint256 coinType) public view virtual override returns (bytes memory) {
 return versionable_addresses[recordVersions[node]][node][coinType];
}

The multi-chain address resolution function supports different blockchain networks through standardized coinType values (ETH uses 60, with other networks defined in SLIP-0044).

The system also maintains record versions through a mapping called recordVersions. Domain owners can increment this version number by calling clearRecords, which invalidates all previous resolution records for that domain.

👉 Explore more about address resolution mechanisms

ENS Domain Registration

While ENS names are represented as NFTs, the underlying technology operates independently of NFT functionality. The registration process is handled by the .eth Registrar contract, which has write permissions to the Registry.

The relationship between the Registrar and Registry ensures that when users purchase ENS names, the appropriate records are created in both systems. Notably, only top-level .eth domains (like name.eth) are represented as NFTs—subdomains (like sub.name.eth) do not receive individual NFT representations.

The token ID for an ENS NFT corresponds to the keccak hash of the domain label. For vitalik.eth, the token ID would be the keccak hash of "vitalik", which is 0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc.

Registration Process

The registration function in the BaseRegistrarImplementation contract follows this logic:

function register(uint256 id, address owner, uint256 duration) external override returns (uint256) {
 return _register(id, owner, duration, true);
}

function _register(uint256 id, address owner, uint256 duration, bool updateRegistry) internal live onlyController returns (uint256) {
 require(available(id));
 require(block.timestamp + duration + GRACE_PERIOD > block.timestamp + GRACE_PERIOD);
 expiries[id] = block.timestamp + duration;
 if (_exists(id)) {
 _burn(id);
 }
 _mint(owner, id);
 if (updateRegistry) {
 ens.setSubnodeOwner(baseNode, bytes32(id), owner);
 }
 emit NameRegistered(id, owner, block.timestamp + duration);
 return block.timestamp + duration;
}

The function includes several important checks and operations:

  1. Domain availability verification
  2. Protection against timestamp overflow
  3. Expiry time setting
  4. Existing NFT burning (if applicable)
  5. New NFT minting
  6. Registry record updates
  7. Event emission

Registration and renewal functions are restricted to authorized controllers, which currently include:

ENS Name Wrapper

The ENS Name Wrapper (ENW) addresses limitations in the original system, particularly regarding subdomain management and NFT representation. This enhancement allows subdomains to be represented as ERC-1155 tokens and enables granular permission control through a fuse mechanism.

Wrapping Process

Wrapping a domain involves transferring its Registry control to the ENW contract. For .eth domains, the process uses the wrapETH2LD function:

function wrapETH2LD(
 string calldata label,
 address wrappedOwner,
 uint16 ownerControlledFuses,
 address resolver
) public returns (uint64 expiry) {
 uint256 tokenId = uint256(keccak256(bytes(label)));
 address registrant = registrar.ownerOf(tokenId);
 
 if (registrant != msg.sender && !registrar.isApprovedForAll(registrant, msg.sender)) {
 revert Unauthorised(_makeNode(ETH_NODE, bytes32(tokenId)), msg.sender);
 }
 
 registrar.transferFrom(registrant, address(this), tokenId);
 registrar.reclaim(tokenId, address(this));
 expiry = uint64(registrar.nameExpires(tokenId)) + GRACE_PERIOD;
 _wrapETH2LD(label, wrappedOwner, ownerControlledFuses, expiry, resolver);
}

This function validates ownership, transfers the NFT to the wrapper contract, updates Registry records, and finally wraps the domain with specified parameters.

Fuse Mechanism

The fuse system provides granular permission control through bitwise flags that can be "burned" to revoke specific capabilities. When a fuse is burned, the corresponding permission is disabled until the domain's expiry date.

Owner-Controlled Fuses (bits 1-16):

Parent-Controlled Fuses (bits 19-32):

Domain States

Based on fuse configurations, wrapped domains can exist in several states:

  1. Unregistered: Not yet registered
  2. Unwrapped: Not wrapped by ENW
  3. Wrapped: Managed by ENW with parent control maintained
  4. Emancipated: Parent control relinquished via PARENT_CANNOT_CONTROL
  5. Locked: Cannot be unwrapped and不受 parent or owner control

These states enable sophisticated management scenarios where domain owners can precisely control what actions subdomain owners can perform.

👉 Get advanced methods for domain management

Frequently Asked Questions

What is the main purpose of ENS?

ENS transforms complex blockchain addresses into human-readable names, making cryptocurrency transactions more user-friendly. Instead of copying and pasting long hexadecimal strings, users can send assets to simple names like john.eth or company.wallet.eth.

How does ENS differ from traditional DNS?

While both systems provide naming services, ENS operates on the Ethereum blockchain with different technical foundations. ENS offers decentralized management, cryptocurrency integration, and resistance to censorship through blockchain technology rather than centralized servers.

Can I transfer my ENS name to another person?

Yes, ENS names represented as NFTs can be transferred like other Ethereum-based tokens. However, specific transfer restrictions may apply if the CANNOT_TRANSFER fuse has been burned in wrapped domains.

What happens if my ENS registration expires?

After expiration, ENS names enter a grace period during which only the original owner can renew them. After this period, the name becomes available for registration by anyone. It's crucial to monitor expiration dates to maintain ownership of valuable names.

How do subdomains work in ENS?

Subdomains allow primary domain owners to create and manage hierarchical namespaces. For example, the owner of company.eth can create employee.company.eth subdomains. With the Name Wrapper, subdomains gain additional functionality including NFT representation and granular permissions.

Is ENS compatible with other blockchains?

Yes, through multi-chain address resolution. ENS resolvers can store addresses for various blockchains using standardized coin types, allowing a single ENS name to resolve to different addresses across multiple networks.