How to resolve Unstoppable Domains’ names

Jeyhun Tahirov
6 min readJul 27, 2021

--

Blockchain domain names are domain names launched as smart contracts on public blockchains.

What sets them apart from traditional domain names (like .com) is that blockchain domains are stored by their owners in their wallet like cryptocurrency, and no third party can change or remove them.

Also, there are no renewal fees for Unstoppable Domains names, so once you own the domain, you own it for life.

In this tutorial, we are going to take a look at Unstoppable Domains, using nothing but HTML, Javascript, and the ethers.js library.

Unstoppable Domains offers a total of 10 different namespaces.

.crypto .nft .888 .x .blockchain .bitcoin .wallet .coin .dao

.zil ( this namespace is located on a separate chain and requires different instructions. You can find them in this medium article )

Each of them can be resolved in exactly the same manner as the .crypto we are showing below.

Final result

To resolve an unstoppable domain, we will need to

  • Tokenize the domain
  • Configure Ethers.js library
  • Make a call and fetch the data

Let’s visualize the resolution process using some of the simplest tools a web developer has: knowledge of HTML and javascript.

Initialize the project folder

The first thing we need to do is create a folder with three files inside: index.html, index.js, and ethers.js.

$ mkdir crypto-resolution
$ cd crypto-resolution
$ touch index.html index.js ethers.js

Your project folder should look exactly like the following:

.
├── index.html
├── index.js
├── ethers.js

Index.html

Let’s open the index.html file and build out the layout for our app.

To create a positive UI experience for the user, we’ll need to build an input bar, a button to trigger the resolution, and a <div> to display our records.

Next, we’ll need to connect js-sha3 (so that we can use the keccak_256 hash function) and ethers.js to communicate with the blockchain contract.

We will need the keccak_256 hash function to calculate ERC-721 token ID for the unstoppable domain. To see a full description of this process, read our namehashing article.

index.html

Index.js

Now that we have our index.html file set up, let’s add some javascript. We can start by inputting some basic code into our index.js file to capture the text from the input field and print it onto our console.

Resolve function

We can open index.html in a browser to make sure everything is connected and launches.

Tokenize your domain by namehashing

Namehashing is an algorithm that tokenizes your domain name in a way that the .crypto smart contract can understand.

To tokenize our domain, we’ll need to split the domain name by the “.” character into separate labels, reverse the array, and reduce it to a single hash. We can do this by implementing a recursive hash function.

We’ll also want to implement an arrayToHex function to get the result as a string, as well as a wrapper function namehash.

Namehashing

Here is the list of expected results with some inputs:

Namehash examples with different inputs

Configure the Ethers.js library

To talk with any blockchain contract using ethers.js, we need to know the following:

  • Ethereum contract address
  • Polygon contract address
  • Contract ABI
  • Ethereum provider
  • Polygon provider

Let’s add the following information to our ethers.js file:

The network and contract addresses are from rinkeby and polygon mumbai test networks respectively. For mainnet, use the following contract addresses: 0xfEe4D4F0aDFF8D84c12170306507554bC7045878 (Ethereum) and 0xA3f32c8cd786dc089Bd1fC175F2707223aeE5d00 (Polygon). Be sure to set the network to mainnet instead of rinkeby.

For the scope of this project, we will only need to use the getData function from the Unstoppable Domains contract.

Next, we’ll need to create a contract instance and create a function to query our contract.

FetchContractData function

By inspecting the contract’s getData function interface, we can see that it requires from us an array of keys and a tokenId. We can get the tokenId by calling the namehash function from above.

Although any string can be stored as a key under the domain, Unstoppable Domains has standardized the keys across many applications.

For this tutorial, we will be looking up the following records:

Records keys and description

Make the call to the contract

Let’s update our resolve function to use the namehash and then look up the desired record keys from the input domain name. We’ll then want to print the result in the console to inspect in more detail.

First, we will query the polygon network and check the ownership. If there is no owner for a domain on polygon network, we need to query the ethereum network.

If we try to resolve the brad.crypto domain with the above keys, we should see the following in the console:

Parsed result from fetchContractData function

data[2] is an array containing all resolved records in the same order in which they were queried. In this case, the first argument is a BTC address and the last one is an ETH address attached to the domain.

Display the records

Since this is a simple example, we won’t get too fancy. We’ll just create a span element for each record containing its key and value, its owner address, and its resolver address. We’ll also want to set the font to red if the record is not found.

DisplayResolution

Before we test it out, let’s make our lives a little easier by implementing a function to combine keys and results into one object.

CombineKeysWithRecords

Now we can easily show the records on our page:

Displaying the result on the page

If we are successful, we should see the following on our page:

Example of successful resolution

Set up error notifications

Now that we have made a successful call, let’s deal with all possible errors that might come up during the resolution.

To do this, we’ll want to create a function to place an error in our records div. We’ll also want to add a boolean argument cleanDom to remove everything from the records div before we place an error for display.

DisplayError

We can easily identify the possible errors by playing around with the app in its current state.

Possible errors and descriptions to them

Once we’ve identified the errors, we will need to update the callback to the fetchContractData function to show the errors to the user.

The final version of the resolve function

Now you can resolve any .crypto domain and display the appropriate error message to your users. Just open the index.html file in your browser and play around with the results to get a better sense of the types of errors that may come up and the types of error messages you might want to include.

For example, you can try to resolve the following domains:

Domains examples

--

--