Cee, five, ef, dee, ef, four, ow, six, seven, oh wait, it’s ow, seven, six, bee… That’s of course not the way you would like to share your Ethereum address or Swarm and IPFS content hash. You copy and send it or scan QR codes but this experience is still inferior to using easy to remember, readable names. In the same way, as DNS solved this problem for IP addresses, ENS has a goal of mitigating this issue in Ethereum ecosystem.

Ethereum Name Service logo

ENS stands for Ethereum Name Service which is a set of smart contracts that provide distributed naming system on the Ethereum blockchain. ENS itself is not a part of Ethereum stack but a community-driven specification that you can easily extend using your custom resolvers for owned names.

In this tutorial, I would like to guide you through the process of registering a test domain on Rinkeby. You can easily apply following steps to other testnets changing only addresses.

Unlike on Mainnet or Ropsten, ENS on Rinkeby does not support .eth domain and is limited to use a .test domain only. Registering .test domain is much quicker as it does not require you to go through the auction process. Test domain also expires after 28 days which makes it good enough to use during a development phase.

Register .test domain

Before we start, let’s download ensutils-testnet.js which contains a few ABIs and helper functions that will make the process more straightforward. Hardcoded ENS address is no good for us since we would like to use Rinkeby, not Ropsten. On the other hand, if you try to register a name on Ropsten, you are all set. Head toward line 220 and change ENS contract address.

var ens = ensContract.at(

'0xe7410170f87102df0055eb195163a03b7f2bff4a'

);

I have prepared a gist with all changes to ensutils needed to make it work on Rinkeby: ensutils-rinkeby.js.

ENS on Mainnet: 0x314159265dd8dbb310642f98f50c066173c1259b

ENS on Ropsten: 0x112234455c3a32fd11230c42e7bccd4a84e02010

ENS on Rinkeby: 0xe7410170f87102df0055eb195163a03b7f2bff4a

Once you did it, connect to running Ethereum node using geth and load the ensutils script.

Before we register, let’s check whether the name you would like to own is available.

> testRegistrar.expiryTimes(web3.sha3("michalzalecki"))

0

If the timestamp returned is 0, or from the past then you can register this name.

> testRegistrar.register(web3.sha3("michalzalecki"), eth.accounts[0], {from: eth.accounts[0]}) 0x986a21970a14258fae1bfc952e731ec88cb94818d78a4c68212da312e6eee2f0

Wait for the blockchain to include transaction. You can now confirm the registration by rechecking the expiration time and the owner.

> testRegistrar.expiryTimes(web3.sha3("michalzalecki"))

1527679534 > ens.owner(namehash("michalzalecki.test"))

"0xY0urAdd355"

Congratulations, you have got yourself a name on ENS!

Public resolver

You own a name, but it does not resolve to anything just yet. You need a resolver. From what I know, there is no official public resolver on Rinkeby at the time of writing. The good news is that anyone can create and deploy one. If you don’t want to create a resolver, then skip to the next section.

Clone the ENS repository, install dependencies and remove the build directory.

git clone https://github.com/ethereum/ens npm install rm -rf build

Change truffle config so you can deploy to Rinkeby.

// truffle.js

module.exports = {

networks: {

rinkeby: {

host: "127.0.0.1",

port: 8545,

network_id: 4

},

},

solc: {

optimizer: {

enabled: true,

runs: 200,

},

},

};

We do not need to deploy all contracts but only PublicResolver. Let’s remove unnecessary migration file and create a new one.

// 2_public_resolver.js

const PublicResolver = artifacts.require("./PublicResolver.sol");



const ENS = "0xe7410170f87102df0055eb195163a03b7f2bff4a";



module.exports = function(deployer) {

deployer.deploy(PublicResolver, ENS);

};

The last step is to run a migration.

./node_modules/.bin/truffle migrate --network rinkeby

If you want to know more about verifying your contract on Etherscan and give your resolver a little credibility, then read my other tutorial:

Resolving domains

We need to point our name to the resolver and set an address to which our domain is resolving. If you do not have your resolver, you can use mine.

> publicResolver = resolverContract.at("0x5d20cf83cb385e06d2f2a892f9322cd4933eacdc") > ens.setResolver(namehash("michalzalecki.test"), publicResolver.address, {from: eth.accounts[0]}) 0x939da269d9cf314ef61cba8226501b2f140383b968b6274f74a99b36bc7b986b

You can now check that ENS keeps the resolver address for your domain

> ens.resolver(namehash("michalzalecki.test"))

"0x5d20cf83cb385e06d2f2a892f9322cd4933eacdc"

I am going to set the domain to point to my account address, but it could be any address at this point.

> publicResolver.setAddr(namehash("michalzalecki.test"), eth.accounts[0], {from: eth.accounts[0]}) 0x621a39c3cb0af3d951102453e11fb6f037918c2a63731c3b519b11d639ce22c0

Now let’s see to which address our domain resolves. We can do it by directly calling public resolver or using the getAddr helper function.

> getAddr("michalzalecki.test")

"0x7d20cb28c496a76173ee828ecacfb08deb379e8d" > publicResolver.addr(namehash("michalzalecki.test"))

"0x7d20cb28c496a76173ee828ecacfb08deb379e8d"

If you would like to resolve addresses on the client or your oracle, then you already have all tools you need. You can use ABI of the resolver and helper function from ensutils. There is also ethereum-ens but it does not work with web3 1.0.

Conclusion

ENS is a great project that tries to make the Ethereum userland more friendly place. While developer experience is not great yet, it is a strong foundation and broad adoption of the popular projects like MyEtherWallet, MetaMask, or Mist.

There is of course more to ENS than what we have covered here. There is a proper documentation available that answers many questions and provides multiple examples. If you would like to learn more about the project and people behind it grab a cup of coffee and watch Nick Johnson’s talk — Ethereum ENS — The Ethereum Name Service.