Using ENS with Data Feeds
Lookup
Manual Lookup
Naming Structure
Chainlink Data Feeds fall under the data.eth
naming suffix. To obtain a specific feed address, prefix this with the assets in the feed, separated by a dash (-).
Pair | ENS Domain Name |
---|---|
ETH / USD | eth-usd.data.eth |
BTC / USD | btc-usd.data.eth |
… | ... |
Subdomains
By default, the base name structure (eth-usd.data.eth
) returns the proxy address for that feed. However, subdomains enable callers to retrieve other associated contract addresses, as shown in the following table.
Contract Addresses | Subdomain Prefix | Example |
---|---|---|
Proxy | proxy | proxy.eth-usd.data.eth |
Underlying aggregator | aggregator | aggregator.eth-usd.data.eth |
Proposed aggregator | proposed | proposed.eth-usd.data.eth |
Naming Structure
Chainlink data feeds fall under the data.eth
naming suffix. To obtain a specific feed address, prefix this with the assets in the feed, separated by a dash (-).
Pair | ENS Domain Name |
---|---|
ETH / USD | eth-usd.data.eth |
BTC / USD | btc-usd.data.eth |
… | ... |
Subdomains
By default, the base name structure (eth-usd.data.eth
) returns the proxy address for that feed. However, subdomains enable callers to retrieve other associated contract addresses, as shown in the following table.
Contract Addresses | Subdomain Prefix | Example |
---|---|---|
Proxy | proxy | proxy.eth-usd.data.eth |
Underlying aggregator | aggregator | aggregator.eth-usd.data.eth |
Proposed aggregator | proposed | proposed.eth-usd.data.eth |
Architecture
Resolver
For each network, there is a single Chainlink resolver, which does not change. Its address can be obtained using the data.eth
domain. This resolver manages the subdomains associated with data.eth
.
Network | Resolver Address |
---|---|
Ethereum Mainnet | 0x122eb74f9d0F1a5ed587F43D120C1c2BbDb9360B |
Listening for Address Changes
When a new aggregator is deployed for a specific feed, it is first proposed, and when accepted becomes the aggregator for that feed. During this process, the proposed
and aggregator
subdomains for that feed will change. With each change, the resolver emits an AddrChanged
event, using the feed subdomain (for example: eth-usd.data.eth
) as the indexed parameter.
Example: If you want to listen for when the aggregator of the ETH / USD feed changes, set up a listener to track the AddrChanged
event on the resolver, using a filter like this: ethers.utils.namehash('aggregator.eth-usd.data.eth')
.
Obtaining Addresses
Reverse lookup is not supported.
Javascript
The example below uses Javascript Web3 library to interact with ENS. See the ENS documentation for the full list of languages and libraries libraries that support ENS.
This example logs the address of the data feed on the Ethereum mainnet for ETH / USD prices.
const Web3 = require("web3")
const web3 = new Web3("https://rpc.ankr.com/eth")
web3.eth.ens.getAddress("eth-usd.data.eth").then((address) => {
console.log(address)
})
Solidity
In Solidity, the address of the ENS registry must be known. According to ENS documentation, this address is the same across Mainnet and Goerli networks:
ENS registry address: 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e.
Also, instead of using readable string names like eth-usd.data.eth
, resolvers accept bytes32 hash IDs for names. Hash IDs can be retrieved from this subgraph or via this npm package eth-ens-namehash.
“ETH / USD” hash: 0xf599f4cd075a34b92169cf57271da65a7a936c35e3f31e854447fbb3e7eb736d
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
// ENS Registry Contract
interface ENS {
function resolver(bytes32 node) external view returns (Resolver);
}
// Chainlink Resolver
interface Resolver {
function addr(bytes32 node) external view returns (address);
}
// Consumer contract
contract ENSConsumer {
ENS ens;
// ENS registry address: 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
constructor(address ensAddress) {
ens = ENS(ensAddress);
}
// Use ID Hash instead of readable name
// ETH / USD hash: 0xf599f4cd075a34b92169cf57271da65a7a936c35e3f31e854447fbb3e7eb736d
function resolve(bytes32 node) public view returns (address) {
Resolver resolver = ens.resolver(node);
return resolver.addr(node);
}
}