Resolving Names

Looking up cryptocurrency addresses

Names can have many types of data associated with them; the most common is cryptocurrency addresses. Defichain Domain supports storing and resolving the addresses of any arbitrary blockchain.

Resolution is a three step process:

  1. Normalise and hash the name - see name processing for details.

  2. Call resolver() on the Defichain Domain registry, passing in the output of step 1. This returns the address of the resolver responsible for the name.

  3. Call addr() on the resolver address returned in step 2, passing in the hashed name calculated in step 1.

Resolution support for the addresses of other blockchains is implemented with an additional overload on addr(). To resolve a non-Defichain MetaChain address, supply both the namehash and the SLIP44 chain ID of the cryptocurrency whose address you want to resolve. For example, to resolve a Defichain Native address, you would call addr(hash, 1129). Note that the returned address will be in binary representation, and so will need decoding to a text-format address.

If you are resolving addr() records, you MUST treat a return value from the resolver of 0x00…00 as that record being unset. Failing to do so could result in users accidentally sending funds to the null address if they have configured a resolver in Defichain Domain, but not set the resolver record!

Looking up other resources

Defichain Domain supports many types of resources besides Defichain addresses, including other cryptocurrency addresses, content hashes (hashes for IPFS, Skynet, and Swarm, and Tor .onion addresses), contract interfaces (ABIs), and text-based metadata.

Resolving these content types follows the same 3-step process detailed above; simply call the relevant method on the resolver in step 3 instead of addr().

Encoding and decoding contenthash

contenthash is used to store IPFS and Swarm content hashes, which permit resolving Defichain Domain addresses to distributed content (eg, websites) hosted on these distributed networks. ENS content-hash javascript library provides a convenient way to encode/decode these hashes.

const contentHash = require("content-hash");
const encoded =
  "e3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f";
const content = contentHash.decode(encoded);
// 'QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4'

const onion = "zqktlwi4fecvo6ri";
contentHash.encode("onion", onion);
// 'bc037a716b746c776934666563766f367269'

const encoded =
  "e40101701b20d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162";

const codec = contentHash.getCodec(encoded); // 'swarm-ns'
codec === "ipfs-ns"; // false

Note for ipns: For security reasons, the encoding of ipns is only allowed for libp2p-key codec. Decoding with other formats will show a deprecation warning. Please read here for more detail.

Coin type and encoding/decoding

To query specific cryptocurrency addresses, you have to call via each coin id (e.g.: 0 for BTC, 1129 for Defichain Native). For Javascript/Typescript, we have @defichaindomains/address-encoder library that allows you to convert

import { formatsByName, formatsByCoinType } from "@defichaindomains/address-encoder";

formatsByName["BTC"];
// {
//   coinType: 0,
//   decoder: [Function (anonymous)],
//   encoder: [Function (anonymous)],
//   name: 'BTC'
// }

To save storage space as well as prevent users from setting wrong token address, the library has encoder and decoder

const data = formatsByName["BTC"].decoder("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa");
console.log(data.toString("hex")); // 76a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac
const addr = formatsByCoinType[0].encoder(data);
console.log(addr); // 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa

Listing cryptocurrency addresses and text records

For cryptocurrency addresses and text records, you need to know the coin type or key names to get the value. If you want to list down all the cryptocurrency addresses and text records the user has set, you have to either retrieve the information from Event or query via Defichain Domain subgraph.

For example

{
  domains(where:{name:"vitalik.dfi"}) {
    id
    name
    resolver{
      texts
      coinTypes
    }
  }
}

will return the following result

{
  "data": {
    "domains": [
      {
        "id": "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835",
        "name": "vitalik.dfi",
        "resolver": {
          "coinTypes": [
            60
          ],
          "texts": [
            "url"
          ]
        }
      }
    ]
  }
}

Reverse Resolution

While 'regular' resolution involves mapping from a name to an address, reverse resolution maps from an address back to a name. Defichain Domain supports reverse resolution to allow applications to display Defichain Domain names in place of hexadecimal addresses.

Reverse resolution is accomplished via the special purpose domain addr.reverse and the resolver function name(). addr.reverse is owned by a special purpose registrar contract that allocates subdomains to the owner of the matching address - for instance, the address 0x314159265dd8dbb310642f98f50c066173c1259b may claim the name 314159265dd8dbb310642f98f50c066173c1259b.addr.reverse, and configure a resolver and records on it. The resolver in turn supports the name() function, which returns the name associated with that address.

Defichain Domain does not enforce the accuracy of reverse records - for instance, anyone may claim that the name for their address is 'alice.dfi'. To be certain that the claim is accurate, you must always perform a forward resolution for the returned name and check it matches the original address.

Reverse resolution follows the same pattern as forward resolution: Get the resolver for 1234....addr.reverse(where 1234... is the address you want to reverse-resolve), and call the name() function on that resolver. Then, perform a forward resolution to verify the record is accurate.

Make sure to compare that the returned names match with the normalised names to prevent from homograph attack as well as people simply using capital letters.

Last updated