Creating your first ‘domain’ name on Ethereum using ENS (Blockchain stack #2)

ENS Domain Names

ENS is the Ethereum Name Service, a distributed, open, and extensible naming system based on the Ethereum Blockchain. It is very similar to registering a domain name and using DNS. I will compare DNS and ENS for each step below.

I’m writing a series of posts on the Blockchain Stack, giving simple but fully coded, step by step examples of how each of the element work both independently and collaboratively. This is the third post in the series, here you can find the intro Blockchain stack #0: Introduction of distributed stack vs LAMP.

Before we jump into this, I have changed my set up to use Geth for the JS console and Parity for the node. The examples moving forward will be using this configuration. Details of how to install Parity and why I changed can be found in the post Ethereum parity fast setup ropsten testnet.

Loading Javascript APIs to the Ethereum ENS contracts

Make sure Parity is running on testnet in a separate terminal and start the geth console.

$ parity --geth --chain ropsten

In a new terminal, download the JS file which contains the APIs to the ENS contracts and run Geth console (attaching to parity) and load the script.

$ mkdir EthereumJS $ cd EthereumJS 
$ curl -O
$ cd ~
$ geth attach > loadScript('./EthereumJS/ensutils.js');

Test it has been loaded correctly:

> testRegistrar.expiryTimes(web3.sha3('name')); { [String: '0'] s: 1, e: 0, c: [ 0 ] }

Creating your first (domain) name on Blockchain

Check you have two accounts and they have ETH. This post tells you how to get Ether on testnet.

First, let’s check if the name has already been registered. When a name is registered it has an expiry set. In this case, you can see ‘ianmonk’ has already been registered, whilst ‘ian-monk’ is not registered.

> new Date(testRegistrar.expiryTimes(web3.sha3('ianmonk')).toNumber() * 1000) Thu Mar 09 2017 18:57:49 GMT+0000 (GMT) > new Date(testRegistrar.expiryTimes(web3.sha3('ian-monk')).toNumber() * 1000) Thu Jan 01 1970 00:00:00 GMT+0000 (BST)

A — Register the name (‘buy the domain’)

Now we are going to register ‘ian-monk’ to your default account [0] and pay for this from your second account [1]. This is the equivalent step of buying a domain name.

> personal.unlockAccount( eth.accounts[1] ); 
> testRegistrar.register(web3.sha3('ian-monk'), eth.accounts[0], {from: eth.accounts[1]});

Check it has been mined:



The latter can be useful because it can show errors.

This should now return your account address:

> ens.owner(namehash('ian-monk.test'))

B — Set the Resolver (set DSN server)

What you have done so far is set who owns this name (your account[0]). Now you can choose what Resolver service will provide the address that this name maps/points to. This is the equivalent on setting the DNS server for your domain name.

In this case we are going to use the publicly defined one named publicResolver (if you view source of ensutils.js you will find publicResolver.address maps to 0x4c641fb9bad9b60ef180c31f56051ce826d21a9a). This time we will use the default account[0] as the ENS protocol will only allow the account owner of the name to change the resolver address.

> ens.setResolver(namehash('ian-monk.test'), publicResolver.address, {from: eth.accounts[0]}); 
0xcb8590303fe605837d085b9c15cf27ea9399a12d72ea0b9ccb2552213f015944 > web3.eth.getTransactionReceipt("0xcb8590303fe605837d085b9c15cf27ea9399a12d72ea0b9ccb2552213f015944");

C — Set the account to map to (Set the IP address in the DSN)

Now we (a) own the name and (b) have told it what service/contract resolver to use. We now need to tell that resolver (publicResolver) what account we want it to map the name to.

Let’s create a new account to reference.

> personal.newAccount() Passphrase:  Repeat passphrase:  "0x1d37a7e0320cb23403cf971ed4194b0e0258aef0"

Check what index was assigned to this new account. My new account was created under accounts[0], pushing the one the name is registered to into [1] — very annoying!

Now, let’s tell the publicResolver to map our name to this new account. You’ll note the first account reference (eth.accounts[0]) is where to map it and the second (eth.accounts[1]) is the account that owns the name (and pays the gas).

> publicResolver.setAddr(namehash('ian-monk.test'), eth.accounts[0], {from: eth.accounts[1]}) "0x4816778387307734159f1a35d7f2730bb025df4f92b50efbcc68a7daec692cdf"

Check it has been mined and then that’s it, you should now be able to resolve your name to an address (client account or contract):

> getAddr('ianmonk.test') "0x1d37a7e0320cb23403cf971ed4194b0e0258aef0"

You can try exiting the console and restarting it to check it has persisted:

$ geth attach > loadScript('./EthereumJS/ensutils.js'); > getAddr('ianmonk.test') "0x1d37a7e0320cb23403cf971ed4194b0e0258aef0"

Well done, you have created your first domain name on Ethereum!

Next in the Blockchain stack series

Next in the series is Your first Ethereum web page (Blockchain stack #3).

Ziggify Blockchain

There’s a team of us that have come together at Ziggify to work on a Blockchain play. We are in the exploration phase, so if you want to get involved or have an idea please get in touch. I’m based in London and enjoy chewing the Blockchain fat over a cuppa or a beer.


Originally published at on February 15, 2017.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.