How to resolve .zil domain names

Jeyhun Tahirov
Unstoppable Domains
6 min readFeb 8, 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.

Unstoppable Domains can store IPFS hashes to make decentralized websites. They can also store cryptocurrency addresses to simplify payments.

In this tutorial, we’ll build a simple app to ‘resolve’ domains — to read the information the domain holds. Here’s the finished product

Our finished tutorial app

First, create a project folder with two files inside: index.html and index.js

$ mkdir zil-resolution
$ cd zil-resolution
$ touch index.js index.html

Your folder structure should look like this:

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

Next, let’s open our HTML page and add some boilerplate code. We are going to use the js-sha256 CDN for encoding the domain.

This is a simple HTML document with a main container in the body. It contains an input field for our user, a button to resolve the domain, and another div where we’ll display the results.

Add javascript to activate the button and layout

Now that we have our index.html file set up, let’s add some javascript. We can start by opening our index.js file and defining two constants:

Сonstants

We’ll discuss the registry contract address later in this guide.

const ZILLIQA_API = “https://api.zilliqa.com/";
const UD_REGISTRY_CONTRACT_ADDRESS = “9611c53BE6d1b32058b2747bdeCECed7e1216793”;

Next, we’ll need to define and attach the function resolve to our HTML button under id="button".

We can start writing this function by taking our input from the text field and preparing to handle an incorrect domain. We will revisit error handling later in this guide.

Any domain that does not end with .zil is out of scope for this guide.

Start of our resolve function

Tokenize your domain by namehashing

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

To tokenize our domain, we’ll need to split the domain 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.

Namehash function
Sample namehash outputs

Here is a list of expected results with some sample inputs:

It is essential to know the difference between Zilliqa namehashing and EIP-137. Zilliqa uses sha256 from SHA-2 instead of keccak256, which is more commonly used in Ethereum.

Let’s use this function to take a namehash of our userInput in index.js.

Resolve function

Get the resolver address

Our next step is to fetch two very important addresses attached to every Unstoppable domain: the owner address and the resolver contract address. We can get them by querying the Unstoppable Domains registry contract.

The owner address, as expected, is the address that owns a domain. The resolver contract address requires a little more explanation. All Unstoppable domains are stored using two main smart contracts: a Registry contract and a Resolver contract.

Contracts description

In order to get the BTC address from a domain, we will need two queries: one to check the registry for the appropriate resolver address and another to check the resolver for the records.

Let’s write a function to make a JSON-RPC POST API request to the Zilliqa blockchain using their gateway. This function will take an array of parameters that we want to send and make a POST call to the Zilliqa API.

FetchZilliqa function

The parameters we need to send are:

  • The contract address we want to query,
  • For the contract field name, use string records,
  • The contract state keys array of strings, which in our case is the domain namehash (this should be the only value in the array).

Let’s update our resolve function and use the fetchZilliqa function:

FetchZilliqa usage example

Now if we query for “brad.zil” we should get a response as below:

Example of response for brad.zil

Order is very important, as the first address in the arguments array is the owner address, and the second one is a resolver contract address.

If we open the index.html file in the browser and type brad.zil as our domain input, we will see the following in the console:

ownerAddress:“0x2d418942dce1afa02d0733a2000c71b371a6ac07”,
resolverAddress: “0xdac22230adfe4601f00631eae92df6d77f054891”

Fetch the records

After we verify that a domain has an owner address, we can query its resolver contract address for its records.

We can use our fetchZilliqa function again, only this time change the parameters to contain the resolver address. For the state keys, we can pass an empty array.

Fetching records with fetchZilliqa function

You must remove the leading 0x from the contract address. This is a requirement of the Zilliqa Blockchain API

We should get an object printed on our console with all the keys registered under that domain. Let’s test it out with domain brad.zil. For your result, you should get something similar to the following in the console.

Results you can get by resolving brad.zil

Display the resolution

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.

DisplayResolution function

Let’s also call this function right after we get the records.

Usage of displayResolution inside resolve function

We should see something like the following on successful resolution.

Example of a successful domain 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. We can easily distinguish some of the use cases for our errors:

Error troubleshooting

For our purposes, 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 function

Although any string can be stored as a key under the domain, Unstoppable domains have standardized some of the keys across many applications.

For the Record is not found error message, we can check if the domain has a BTC address. If not, we can show the error without cleaning the entire DOM.

We will need to display errors in two functions: resolve and displayResolution. Here is how both functions should look after all of the updates:

Final resolve function
Final displayResolution function

Now you can resolve any .zil 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.

Some domains to test

--

--