{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-web3/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["partial"]},"type":"markdown"},"seo":{"title":"Namehashing","description":"The developer documentation portal and API reference for Unstoppable Domains.","siteUrl":"https://docs.unstoppabledomains.com","keywords":"unstoppable domains developer portal, api reference docs","lang":"en-US","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"namehashing","__idx":0},"children":["Namehashing"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Namehashing is an algorithm that converts a domain name in a classical format (like ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["www.example.crypto"]},") to ERC-721 token ID. All ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".crypto"]}," contracts accept a domain name as a method argument in the form of an ERC-721 token. Namehashing is defined as a part of the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://github.com/ethereum/EIPs/blob/master/EIPS/eip-137.md#namehash-algorithm"},"children":["EIP-137"]}," standard. See the standard for a text description of the algorithm."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To verify an implementation of the namehash algorithm, use the following reference table:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Domain Name"},"children":["Domain Name"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"ERC721 Token"},"children":["ERC721 Token"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["."]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0x0000000000000000000000000000000000000000000000000000000000000000"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["crypto"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0x0f4a10a4f46c288cea365fcf45cccf0e9d901b945b9829ccdb54c10dc3cb7a6f"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["example.crypto"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0xd584c5509c6788ad9d9491be8ba8b4422d05caf62674a98fbf8a9988eeadfb7e"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["www.example.crypto"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0x3ae54ac25ccd63401d817b6d79a4a56ae7f79a332fe77a98fa0c9d10adf9b2a1"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["a.b.c.crypto"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0x353ea3e0449067382e0ea7934767470170dcfa9c49b1be0fe708adc4b1f9cf13"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"generating-a-domain-namehash","__idx":1},"children":["Generating a Domain Namehash"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can generate the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"/web3/getting-started/glossary#namehash"},"children":["namehash"]}," of a domain using the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"/web3/apis/resolution/openapi#operation/DomainsController.getDomain"},"children":["Resolution Service"]},". You can also use ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://swolfeyes.github.io/ethereum-namehash-calculator/"},"children":["online tools"]}," to calculate the namehash of the domain."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"/**\n * Resolves the namehash for a given domain.\n * \n * @param {string} domain - The domain name to resolve\n * @returns {Promise<string | null>} The resolved namehash or null if not found\n * \n * @throws {Error} When no namehash can be resolved for the given domain\n */\nasync function resolveNamehash(\n  domain: string, \n): Promise<string | null> {\n\n  try {\n    const response = await axios.get(\n      UNSTOPPABLE_API_BASE_URL + 'domains/' + encodeURIComponent(domain), \n      {\n      headers: { 'Authorization': 'Bearer ' + UNSTOPPABLE_API_KEY }\n      }\n    );\n\n    const metadata = response.data.meta;\n      \n    const namehash = metadata['namehash'];\n\n    if (namehash) return namehash;\n\n    throw new Error('No namehash found for ' + domain);\n  } catch (error) {\n    console.error('Namehash resolution error:', error);\n    return null;\n  }\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"reverse-lookup","__idx":2},"children":["Reverse Lookup"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Fundamentally, namehashing is a one-way operation. It recursively hashes the labels using the SHA-256 hash function. If one possesses a precomputed table of all hashes and corresponding domains reverse lookups are possible. This table can be reconstructed using the events on the CNS and UNS Registry ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["NewURI"]}," event."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"json-rpc","__idx":3},"children":["JSON RPC"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The UNS and CNS metadata APIs track all domain names with their corresponding namehash. That makes it possible to obtain an original domain name from token metadata which can be retrieved from the token metadata URI."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The token metadata URI can be retrieved via ETH RPC call to ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://github.com/unstoppabledomains/uns/blob/1ee37ef421bb9539b7254b9b0add5215c94282ec/contracts/ProxyReader.sol#L38"},"children":["ProxyReader#tokenURI"]},". This works for CNS and UNS."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Now, the domain name along with other metadata can be retrieved by performing a simple GET request using the token metadata URI."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For example:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"// Get a proxy reader contract instance using web3 or ethers\nlet proxyReaderContractInstance = new Contract(address, abi);\n\n// call the tokenURI method\nlet tokenUri = await proxyReaderContractInstance.tokenURI(\"0x756e4e998dbffd803c21d23b06cd855cdc7a4b57706c95964a37e24b47c10fc9\");\n\n// GET data from URI\nlet metadataResponse = await fetch(tokenUri);\n// Parse it as json\nlet metadata = await metadataResponse.json();\n\n// Retrieve the domain name from metadata\nconsole.log(metadata.name);\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"newuri-events","__idx":4},"children":["NewURI Events"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When a domain is created its name and token ID are logged using a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["NewURI"]}," event. This event can be looked up in order to reverse the namehash of a domain. This approach also works for CNS and UNS."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For an implementation example, see the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://github.com/unstoppabledomains/resolution/blob/221170af1ece1d97c02c86d6d1645d4c5761005e/src/Resolution.ts#L613"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["unhash"]}," function"]}," of the resolution library."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Note that regardless of the way a namehash is reversed, it should always be forward-validated by hashing the retrieved domain name. In order to ensure the integrity of the retrieved domain name."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"public-api","__idx":5},"children":["Public API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Unstoppable Domains maintains a public-facing API which can be used to obtain the information of a domain using its namehash. To learn more, visit the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"/web3/apis/metadata/openapi#operation/domains_getMetaData"},"children":["Get Metadata for a Domain"]}," documentation."]}]},"headings":[{"value":"Namehashing","id":"namehashing","depth":1},{"value":"Generating a Domain Namehash","id":"generating-a-domain-namehash","depth":2},{"value":"Reverse Lookup","id":"reverse-lookup","depth":2},{"value":"JSON RPC","id":"json-rpc","depth":2},{"value":"NewURI Events","id":"newuri-events","depth":2},{"value":"Public API","id":"public-api","depth":2}],"frontmatter":{"title":"Namehashing | Unstoppable Domains Developer Portal","description":"This page details the Namehashing algorithm and the features of the ERC-721 token standard.","seo":{"title":"Namehashing"}},"editPage":{"to":"https://github.com/unstoppabledomains/dev-docs/blob/main/web3/getting-started/domain-registry-essentials/namehashing.md"},"lastModified":"2026-04-10T16:45:57.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/web3/getting-started/domain-registry-essentials/namehashing","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}