Indexing the Ethereum Name Service
Over the past 6 months I have been proactively engaging with the ICANN ecosystem to support in answering questions relating to how ENS can responsibly integrate with the Domain Name System (DNS).
In the process I engaged in some interesting conversations, including one with Nathan Alan from OXIL who was co-author of an interesting piece entitled Understanding the Collision Risks: Where Blockchain Identifiers Meet Domain Names. That conversation included discussion of data sourcing for research purposes.
Over the years I have iterated on an indexer for ENS data for usage as a backend provider for my product EthTools.com. I figured that I would polish it, such that I could export any data necessary for research needs. In the process I fell down a rabbit hole - each iteration brought to light interesting nuances, and fun possibilities. Ultimately I ended up with two products:
- ENSIndexer.com - Indexing infrastructure for ENS data.
- ENSWhois.com - A WHOIS service for quickly sourcing data about ENS names.
There is a lot more to these seemingly simple products, so let's dive in.
Indexing
ENS has a number of smart contracts that provide different pieces of functionality. They include the Registry, the Base Registrar, the ETH Registrar Controller, the NameWrapper, Reverse Registrars, DNS and Subdomain Registrars, and multiple generations of Public Resolvers. Noting the immutability of smart contracts, the upgrade path for ENS has necessitated new and modified contracts over the years. In total, over 20 contracts have been deployed since ENS launched in 2017 - including the original Vickrey auction registrar, five controller versions, and nine public resolver iterations. Tracking all of them requires a purpose-built, ENS-specific indexer and extensive domain knowledge.
Whilst ENS state is necessarily stored in the storage associated with those contracts, it is somewhat obfuscated by how the data is mapped under the hood. Many contracts utilize the labelhash and the namehash - hashes of name data calculated using the unidirectional keccak256 hashing function. That means that you cannot inherently discern the original string from which the hash was created. Even if you could, it is not possible to discern the storage slots in which underlying data is stored unless you know the keys in advance - you cannot simply iterate through 'all ENS names'.
Instead we take advantage of the events emitted by the smart contracts. This is the same approach taken by The Graph, a generic indexing tool that has historically been used by ENS, and ENSNode, an ENS-specific indexing tool.
Sync Speed
When it comes to indexing, one of the main metrics that is always discussed and debated is sync speed. Generally shared benchmarks always come with nuance. My personal opinion is that as long as sync speed is reasonable, the real things that one should be looking at are simplicity, completeness, and usability.
The indexer processes events from over 20 ENS contracts starting from block 3,327,417 (March 2017) and synchronizes the full dataset in ~12 hours on a basic entry-level machine (8 vCPU, 16GB RAM). The resulting dataset is structured for efficient real-world queries - 'give me all domains owned by 0x123.. that expire in the next 6 weeks'. Snapshotting can of course be utilized for instantaneous sync for indexer redundancy, but even without it, a tool that syncs while you sleep is plenty fast enough.
Simplicity
In the blockchain space, I almost daily see products waxing lyrical about their cool architectures - all of the exciting tools they use to hyperoptimize performance. In reality the same can be achieved with basic tooling, and simplicity makes codebases more accessible and understandable.
The indexer is built with JavaScript, PostgreSQL, and Redis. No subgraph compilation, no custom query languages, no external indexing infrastructure dependencies. It runs on Bun as a set of systemd services on a single Linux server.
REST
The indexer exposes a well-documented RESTful API. The Graph - as implied by the name - uses GraphQL. For an implementation-specific use case like this, where the data model is known and the query patterns are predictable, REST is simpler to integrate, faster to serve, and easier to cache.
Ownership Resolution
One of the more subtle challenges in ENS indexing is determining who actually owns a domain. Ownership can be asserted at multiple contract layers - the Registry, the Base Registrar, and the NameWrapper - and these can disagree. The indexer computes an effective_owner_address for each domain using a priority hierarchy (wrapper > registrar > registry), giving consumers a single reliable answer.
Reverse Resolution
When an address sets a primary ENS name, the indexer resolves it using a tiered strategy: first checking for a NameChanged event in the same transaction (zero RPC cost), and falling back to an on-chain resolver.name() call only when necessary. This is handled by a dedicated Reverse Name Service that writes resolved names to an address_primary_names table.
Rainbow Tables
A rainbow table is 'a precomputed table for caching the outputs of a cryptographic hash function'.
In the context of ENS, a rainbow table is necessary to create a full index of ENS names. The reason is that whilst modern ENS contracts emit raw label and name data when an ENS interaction occurs, historically this was not always the case.
The Graph have very kindly open-sourced (graph-protocol/ens-rainbow) a dataset which we use as a starting point. On top of this, the indexer employs additional label discovery mechanisms - including LLM inference, web search, and external APIs - to recover names that the base dataset misses.
Unfortunately it is still not possible to recover all ENS labels. Given the nature of some registered names, complete recovery is likely impossible. This is an area I will continue to refine.
Offchain & L2 Subnames
ENS increasingly supports offchain and L2-based subnames - for example, subnames issued under base.eth or celo.eth that resolve via CCIP-Read rather than on-chain state. These names do not emit events on Ethereum mainnet, which means they are not currently captured by the indexer. This is a known limitation and something I intend to address in future iterations.
Infrastructure
Each indexer node is provisioned via a single-click deployment system that generates a complete server - systemd services, environment configuration, database, and monitoring dashboard - from scratch in minutes. No Kubernetes, no Docker orchestration, no CI/CD pipeline.
Each node exposes a real-time monitoring dashboard tracking sync state, service health, and queue depths. Beyond monitoring, the infrastructure includes search and bulk lookup tooling for inspecting indexed data - useful for debugging, research, and data validation. For a deeper look at the indexer's internals, see How the Indexer Works. The API itself is documented here.
The Network
The indexer network currently runs across multiple independent nodes, each provisioned through the same automated deployment pipeline. The network server polls each node periodically to verify its operation and data integrity. Connected nodes are displayed on the ENSIndexer.com homepage alongside their sync state.
The network exposes RESTful API endpoints that proxy queries to the underlying indexer nodes. This approach is architecturally similar to how dRPC handles RPC requests - consumers get a single endpoint backed by multiple independent data sources.
On Decentralization
An inevitable question: isn't a centralized API antithetical to the ethos of blockchain?
I think this concern, while understandable, is misplaced. In practice, virtually every application that interacts with ENS data today does so through an intermediary - whether that's The Graph, Alchemy, Infura, or a custom backend. The blockchain itself does not expose ENS data in a format that applications can efficiently query. An indexing layer is not optional; it is a practical necessity.
The important thing is not whether an API exists between the consumer and the chain, but whether the data can be verified. And it can:
- The blockchain remains the canonical source of truth. Any indexed record can be checked against on-chain state.
- Every piece of data in the indexer is derived from smart contract events - the same events visible to anyone running an Ethereum node. The raw event data is stored alongside processed records, providing a complete audit trail of how each domain record was derived.
- The network runs across multiple independent nodes. Responses can be cross-referenced.
This is not meaningfully different from how DNS works today. Authoritative nameservers are the source of truth; resolvers and WHOIS services provide queryable interfaces on top. Nobody runs their own recursive resolver to look up a domain - they use an API. ENS will be no different, and pretending otherwise is an obstacle to adoption.
WHOIS
My first job in the domain name industry was building an aftermarket for domain names. I have always been fascinated by the ability to source ownership information about a domain name. Ultimately, if you can't discern who owns a domain name, then it becomes impossibly hard to acquire it. This leads to inefficient economic allocation of domain names - The economics of domain names.
GDPR, other data privacy regulations, and the growing popularity of WHOIS privacy services have meant that accessing ownership data is now incredibly hard in the DNS space. RDAP :|
In the ENS world, it is impossible to discern personally identifying information about a domain name owner unless they choose (or inadvertently) reveal it. For many ENS users, privacy isn't a bug - it's the primary feature. It is however still possible to get interesting data from an ENS dataset:
- Which address owns a name
- How many other names do they own, and what are they?
- What is the history of a name? Who owned it previously?
- What is/was an address's primary ENS name?
In the DNS world, products like WhoisXMLAPI and DomainTools have built significant businesses servicing these needs. As far as I am aware, no equivalent has existed in the ENS world.
I intentionally kept the indexer product light - its job is to index. Instead I built a dedicated product on top of it for accessing ENS domain intelligence. Noting that I am ultimately a domain name guy, I looked up ENSWhois.com and it was available. Shrug.
ENSWhois.com provides:
- WHOIS Lookup - owner, resolver, expiry, registration date, effective ownership across contract layers
- Ownership History - full chronological record of every ownership change, with addresses and transaction references
- Resolver History - track which resolvers a name has used over time
- Event Timeline - every on-chain interaction with a name, from registration through renewals, transfers, and wrapper operations
- Portfolio View - see all names held by a given address, with expiry and status data
Future iterations will expand collection analysis features and cross-referencing tools.
The ENS Indexer API is available at ENSIndexer.com and ENS domain lookups at ENSWhois.com. If you're building on ENS and need reliable access to ownership, resolution, and history data - get in touch.