In-Depth Exploration of the ENS System

Overview

The Ethereum Name Service (ENS) is an open, extensible naming system built on the Ethereum blockchain, currently the most widely used naming protocol within the Ethereum ecosystem. ENS transforms hard-to-read Ethereum addresses like 0x742d35Cc6634C0532925a3b844Bc454e4438f44e into human-friendly names such as vitalik.eth.

This guide assumes readers have intermediate Solidity programming knowledge. If you can understand standard ERC-20 contract implementations, you’ll be able to follow this material. For beginners, we recommend first studying Foundry Tutorial: Writing, Testing and Deploying ERC-20 Smart Contracts.

👉 Discover how ENS revolutionizes blockchain accessibility

Core Architecture

The ENS resolution system comprises two fundamental components:

1. Registry Contract

The Registry serves as the foundational smart contract for ENS queries, maintaining three critical pieces of information:

  1. Domain owner (owner)
  2. Domain resolver (resolver)
  3. Time-to-live cache duration (TTL)

Domain owners can delegate management privileges to operators through the registry.

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

2. Resolver Contracts

Resolvers execute actual domain resolution. Any smart contract complying with ENS standards can function as a resolver, allowing custom record types. Current resolver implementations support:

  • Ethereum addresses
  • Cross-chain addresses (EVM-compatible chains)
  • Content hashes (IPFS, Swarm)
  • Text records (DNS, email, social profiles)

For complete specifications, consult ENS Improvement Proposals (ENSIPs) and the reference Resolver.sol implementation.

Resolution Process Flow

  1. Namehash Conversion: Applications first convert human-readable names to namehash identifiers
  2. Resolver Lookup: The registry’s resolver() function retrieves the associated resolver contract
  3. Record Query: The resolver’s specific functions (e.g., addr()) return requested data

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

Namehashing Mechanism

ENS uses a hierarchical hashing system called namehash to maintain domain relationships. For vitalik.wallet.eth:

  1. Name Normalization: Applies UTS46 standard for ASCII compatibility (case-insensitive)
  2. Recursive Hashing: Processes labels right-to-left to preserve hierarchy

“`python
from Crypto.Hash import keccak

def namehash(name: str):
labels = name.split(“.”)[::-1] # Reverse for processing
node = b’\x00′ * 32
for label in labels:
label_hash = keccak.new(data=label.encode(), digest_bits=256).digest()
node = keccak.new(data=node + label_hash, digest_bits=256).digest()
return node.hex()
“`

Key properties:
– Parent domains control subdomains through setSubnodeOwner()
– Enables permission management across domain levels
– Implemented in Solidity via keccak256(abi.encodePacked())

Address Resolution

Resolvers implement multi-chain address support through standardized coin types:

“`solidity
mapping(uint64 => mapping(bytes32 => mapping(uint256 => bytes))) versionable_addresses;

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

Reference implementations:
– Ethereum (CoinType 60): ENSIP-1
– Multi-chain: ENSIP-9
– CoinType registry: SLIP-0044

👉 Explore multi-chain address management with ENS

ENS Registration System

.ETH Registrar Contract

  • Address: 0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85
  • Function: Manages .eth domain registrations as ERC-721 NFTs
  • TokenID: keccak256(label) of the registered name (e.g., vitalik)

Registration flow via register():

solidity
function _register(uint256 id, address owner, uint256 duration, bool updateRegistry) internal {
require(available(id));
expiries[id] = block.timestamp + duration;
if (_exists(id)) _burn(id);
_mint(owner, id);
if (updateRegistry) ens.setSubnodeOwner(baseNode, bytes32(id), owner);
}

Controller Architecture

Registration occurs through authorized controllers:

  1. Legacy Controller: 0x283Af0B28c62C092C9727F1Ee09C02CA627EB7F5
  2. Name Wrapper: 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401
  3. Governance: 0xCF60916b6cb4753f58533808fA610FCbD4098EC0 (Safe multisig)

ENS Name Wrapper

Introduced to solve key limitations:
1. Subdomains couldn’t be NFTs
2. Parent domains lacked granular control over subdomains
3. Permission management was all-or-nothing

Wrapping Process

solidity
function wrapETH2LD(string calldata label, address wrappedOwner, uint16 fuses, address resolver) public {
uint256 tokenId = uint256(keccak256(bytes(label)));
registrar.transferFrom(registrant, address(this), tokenId);
registrar.reclaim(tokenId, address(this));
_wrapETH2LD(label, wrappedOwner, fuses, expiry, resolver);
}

Fuse Permission System

Bitmask-based permissions with expiration:

Fuse Bit Description
CANNOT_UNWRAP 1 Prevents unwrapping
CANNOT_TRANSFER 4 Locks NFT transfers
CANNOT_CREATE_SUBDOMAIN 32 Disables subdomain creation
PARENT_CANNOT_CONTROL 65536 Emancipates from parent control

Domain States

  1. Unwrapped: Traditional ENS record
  2. Wrapped: Parent maintains control
  3. Emancipated: Parent control revoked
  4. Locked: Permanent wrapper state

Frequently Asked Questions

How do I check if a domain is available?

Query the registrar’s available() function with the name’s keccak256 hash. Domains are available if expired beyond the 90-day grace period.

Can I transfer a wrapped subdomain?

Only if the CANNOT_TRANSFER fuse isn’t burned. Parent domains can restrict this permission before emancipating subdomains.

What’s the difference between .eth and other TLDs?

.eth domains:
– Are native ENS NFTs
– Have automatic emancipation
– Use the permanent registrar
– Support ETH payment for registration

How do I set up multi-chain addresses?

Use the resolver’s setAddr(bytes32 node, uint256 coinType, bytes memory address) function with the appropriate SLIP-0044 coin type.

Can I recover an expired domain?

During the 90-day grace period, only the previous owner can renew. After grace period, anyone can register the expired name.

How does name wrapper improve security?

It enables:
– Granular permission controls
– Non-fungible subdomains
– Permanent locking mechanisms
– Hierarchical management structures

👉 Master ENS domain management with our advanced guide