ENS, short for Ethereum Name Service, is to DNS what Bitcoin is to Money. It is meant to be the decentralised alternative to manage naming on decentralised infrastructure.
And manage what kind of naming?
The limit is your imagination since ENS allows multiple interfaces, including custom ones, but common uses for ENS domains include pointing to other Ethereum addresses for transactions (which is supported by many wallets including Metamask) to pointing to a decentralised website by storing an IPFS hash.
For example, the domain codeclimbing.eth
points to both a wallet address and an IPFS hash which is a copy of this blog. Note how the domain ends with .eth
. ENS domains end with .eth
.
The goal of this article is to give a quick and dirty overview of ENS so you can quickly get started doing projects on it or simply understanding the system for your personal interest.
How to Register and Manage ENS Domains
The easiest way to register and manage ENS domains and subdomains is through the official frontend application.
Here the link: https://app.ens.domains/
You can do all sorts of things including settings what your domain will point to.
This is just a frontend application, of course. The domains themselves are not on some server. They are stored on the Ethereum blockchain in a smart contract. Therefore, you will need Metamask and some Ether to perform the transactions necessary to interact with the ENS system.
Note that you can also use test networks such as Ropsten to play around with ENS and play with the functions.
Overview of the ENS Smart Contracts
There are three important ENS smart contracts
1. The first smart contract is the following: https://etherscan.io/address/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85
This contract is the owner of the .eth
node. Because this contracts owns the .eth
node, it also owns all its sub nodes, which is all the possible labels that can go before .eth
, such as xyz.eth
or codeclimbing.eth
. Since that contract owns the .eth
node, it is also the contract that has the right to distribute .eth
domains.
The ownership system works the same way for my domain. I own codeclimbing.eth
, therefore I have the ability to give away its subdomains. For example, I could create a sub node with the label hello
such as hello.codeclimbing.eth
.
This new subdomain is now a new node and if I wanted to I could create a sub node again. ENS works on this idea of nodes (such as codeclimbing.eth
) to which a new label can be prefixed, such as hello
to create hello.codeclimbing.eth
.
2. The storage smart contract
The second smart contract is the storage smart contract: https://etherscan.io/address/0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e
You can also find the address of that contract by looking at the variable called ens
in the owner contract here: https://etherscan.io/address/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85#readContract.
It makes sense, since the owner contract must interact with the storage contract in order to assign subnodes.
Here’s an interesting exercise. In the storage contract, find the owner
function and see the result of the following input: 0x39a02f89d5906f01fbc39e7367e91e14e5a9bb671a2921ce3b7619ff284f9c2a
The function will return an address which should correspond to the controller
address of the codeclimbing.eth domain, as you can see here: https://app.ens.domains/name/codeclimbing.eth
The value 0x39a02f89d5906f01fbc39e7367e91e14e5a9bb671a2921ce3b7619ff284f9c2a
is the node value corresponding to codeclimbing.eth
. I will explain a bit later how I derived the value.
Next try the following: 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae
Do you recognise the resulting address? Yes, that’s the owner contract of .eth
!
Of course, that means the eth root node has its own page on the frontend.
https://app.ens.domains/name/eth
3. The Public Resolver Contract
https://etherscan.io/address/0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41
Okay, so this resolver contract you could live without and just make your own. The one above is the official one from ENS so we’ll stick with it. Basically, it determines how the domain will resolve.
The most important function is supportsInterface
. It determines the interfaces to which the domain can resolve to whether it is a wallet address, an IPFS hash or something custom to your liking. Creative developers can create their own interfaces for their application if they want it to.
Everything that a domain points to is stored in the resolver contract. For example, in the contentHash
function input the node of codeclimbing.eth
which is 0x39a02f89d5906f01fbc39e7367e91e14e5a9bb671a2921ce3b7619ff284f9c2a
.
The return value is the IPFS hash of this site!!
How Nodes and Labels are Represented in the Smart Contracts
As you have seen above, when interacting with the contract we do no input directly codeclimbing.eth
instead we use this long hexadecimal number 0x39a02f89d5906f01fbc39e7367e91e14e5a9bb671a2921ce3b7619ff284f9c2a
. That is because the string codeclimbing.eth
is not stored in the contract, instead we store a sha3 hash that is computed recursively through the namehash algorithm. This allows all nodes to be saved with a value of fixed length, instead of a variable length if we saved the domain name directly.
It also provides a certain amount of anonymity when registering new domains.
Similarly, when it comes time to input a label (a value with no dots such as codeclimbing
) into the contract, we must use its sha3 hash.
To calculate the namehash value there’s the following package that is useful: https://www.npmjs.com/package/ethereum-ens
Finally, here’s a simple node.js script to get those values.
const namehash = require('eth-ens-namehash')
const web3 = require('web3')
const domain = 'codeclimbing.eth';
const label = 'codeclimbing';
console.log('label hash', web3.utils.sha3(label));
console.log('namehash', namehash.hash(domain));
Practical JS Libraries to Use with ENS
Just to end things on a practical note, here are some libraries I recommend to use with ENS.
Web3.js: https://www.npmjs.com/package/web3 Any self-respecting Dapp developer should know this library. Web3.js is also able to resolve ENS domains to Ethereum addresses in transactions. So cool!
eth-ens-namehash: https://www.npmjs.com/package/eth-ens-namehash You will need this to calculate the namehash of a domain. Also, make sure you do namehash.normalize() in your dapp before hashing! (Here is info on name normalization: https://docs.ens.domains/contract-api-reference/name-processing)
ethereum-ens: https://www.npmjs.com/package/ethereum-ens This package will simplify you life for operations such as setting resolvers, owners, etc… Plus it takes care of name hashing and name normalization for you.
Conclusion
You now know the most important facets of ENS and should be able to use it in Dapps.
As you can see, ENS is not that complicated and quit easy to understand.
It’s truly amazing how such a simple system can be so powerful. It is a small step for ENS, but a big one for decentralisation!
Learn More!
Finally, here’s a link to the previous week’s article on how to access the site an ENS domain points to: https://codeclimbing.com/how-to-visit-ens-enabled-websites-your-gateway-to-web3/