ENS Layer2 and offchain data support


With the proliferation of layer 2 solutions for Ethereum that are starting to reach maturity, it's important that ENS is able to provide resolution services across the entire ecosystem, as well as making it possible for ENS users to take advantage of the efficiencies made possible by Layer 2 solutions. Subsequent to a post by Vitalik that suggested a possible means for this, the ENS team and the wider ENS and L2 community have been working on a general-purpose "Layer 2 bridge" that makes cross-platform interoperability possible for both ENS and other applications that need to be able to retrieve data from a variety of offchain sources (any data that resides outside of Ethereum Mainnet also known as layer 1/L1. This includes both propriety database and layer 2/L2 solutions such as Optimism, Arbitrum, Starknet, ZKSync, and so on) in a trustless fashion and came up with standards.
EIP 3668 (Final) allows for offchain (including Layer 2/L2) lookups of data in a way that is transparent to clients and provides contract authors to implement whatever validation is necessary; in many cases, this can be provided without any additional trust assumptions over and above those required if data is stored onchain.
EIP 5559 (Draft) provides a mechanism in which smart contracts can request various tasks to be resolved by an external handler. This provides a mechanism in which protocols can reduce the gas fees associated with storing data on mainnet by deferring the handling of it to another system/network. These external handlers act as an extension to the core L1 contract.
ENSIP 10 (Draft) is a general way to resolve wildcard (eg: *.foo.eth) on L1. Issuing subdomains and moving the resolution of the parent name offchain allows dapps to create subdomains offchain yet make it accessible through L1.

Steps required for Dapps and wallets to support offchain data lookup.

If your dapps or wallets use one of those libraries, the EIP 3668 and ENSIP 10 support will be built in, so simply update the library when ready. EIP 5559 is still in its early stage of draft and the content will be evolving


ethers.js 5.6.2 supports both EIP3668 and ENSIP 10.
No code change is required as long as your app is interacting with ENS through etherjs ENS methods.
To try out these features, offchainexample.eth points to so-called "offchain resolver" that fetches data from JSON configuration file hosted on google app engine. It will reply data to any record for offchainexample.eth and its subdomain record such as 2.offchainexample.eth. The example resolver is not using L2 data but the same mechanism works when the L2 resolver becomes ready.
const { ethers } = require("ethers");
const url = `${process.env.API_KEY}`;
const provider = new ethers.providers.JsonRpcProvider(url);
async function main() {
let resolver = await provider.getResolver("1.offchainexample.eth");
let address = await provider.resolveName("1.offchainexample.eth");
let email = await resolver.getText("email");
console.log({ resolver: resolver.address, address, email });
The expected output is as follows.
$node index.js
resolver: '0xC1735677a60884ABbCF72295E88d47764BeDa282',
address: '0x41563129cDbbD0c5D3e1c86cf9563926b243834d',
Please refer to offchain resolver client example code for more detail.

Other supported libraries.

Wallets integrated

Steps required for Dapps and wallets to issue subdomains offchain

If you wish to issue subdomains using offchain data storage, please follow offchain resolver as a reference point. The example uses a flat file as a data source but can easily be replaced with database calls.
The following projects have integrated with the Offchain resolver for issuing their subdomains
Offchain resolver provides an easy way to store data offchain but please be aware of some trade off. Users have to trust that gateway server returns the correct data. Some offchain resolver returns attestation by signing the signature. To do so, the owner of the parent domain that issue subdomains have to host the gateway on their own and have to have a private key to sign. If the gateway server is compromised, there is a risk that the subdomain address are redirected to the malicious addresses.
To minimise the trust to the gateway, we are currently working on L2 resolvers

L2 Resolver

In a L2 rollup system, contract state hashes are stored on-chain, along with the transaction calls and arguments logged as calldata. a rollup has a mechanism to verify the state of their chain on L1, either instantly or optimistically.
ENS integration utilizes this mechanism in the gateway. The gateway retrieves the data from L2 along side with the proof (often via eth_getProof) and returns back to the caller. The caller passes the data to L1 resolver contract to verify its state and data(more detail). As long as L1 contract can verify the state and storage of the L2 data, users no longer need to trust the gateway itself. If a gateway service is compromised, the worst can happen is that the gateway stops responding data ( when that happens, the owner of the resolver can simply startup new gateway and update the L1 contract to return the new gateway address). The parent owner does not even have to host the gateway services by themselves but can use third party gateway services.
To assess whether a L2 rollup system can integrate with ENS, please see the following steps.
  1. 1.
    Does your chain use same address format as the ones used in Ethereum? = Some ZKRollup chains use different address format. If that's the case, you need to add your wallet address format into ENS multicoin type. Please refer to Starknet support PR as a reference.
  2. 2.
    Does RPC of the chain return eth_getProof? If not, it requies a way to retrieve a storage proof to verify on Ethereum L1
  3. 3.
    Does the rollup contract have a function to return information of the latest L2 block committed to Ethereum L1? For Optimistic Rollup, it needs both the committed and finalised (after challenge period) block information. The blockhash is required to call eth_getProof equivalent function on L2
  4. 4.
    Is there a way to verify on L1 contract that the state root returned from L2 is valid?
  5. 5.
    Is there a way to verify that the storageProof is included in the state root? For Optimistic rollups, we can use Lib_SecureMerkleTrie library developed by the optimism team. If the chain doesn't support Patricia Merkle Trie, it needs own library
For more details, please refer to the prototype implementations of an OP Stack resolver. Starknet has a community proposal to add a support.


Is the change backwards compatible?

Yes. The existing names on L1 will continue working without clients nor applications supporting these standards. Only names that are outside of L1 will not be resolved.

Will L2/offchain data be supported by GraphQL?

Once each L2 is officially supported, we will need to spin up a subgraph for each L2 bridge, and we will use schema stitching to make using them transparent to callers.
For names that are not hosted on a supported L2, we won't be able to fetch data that are normally only available on the subgraph

How do you support other EVM compatible chains?

Non-L2 chains lack ways to verify data on L1 in the trustless manner. The alternative is for chain bridge operators to act as a trusted third-party and hosts the offchain gateway, or individual dapps hosts own gateway and sign each data with the private key of the ENS name.

Can I issue a new tld unique to an offchain environment?

No. Please read "Why ENS Doesn't Create More TLDs: Responsible Citizenship in the Global Namespace" for more detail. Alternatively we suggest that you import DNS names as ENS like, and

Can I set a primary name to names on offchain?

Yes, you can. However, reverse registrar (it is a hidden top-level domain starting with .addr.reverse) currently resides on L1; hence you have to pay gas on L1. We may consider moving the reverse registrar to L2 in future.

Can I register .eth name on offchain?

Only when we migrate .eth name to a specific L2 as one of the last steps of our migration after finding out which L2 supports ENS integration the best.

How do I handle contract addresses?

Unlike EOA (Externally Owned Account), contract based accounts such as multisig may only be accessible in certain chains. ENSIP-11 allows a single name to hold different addresses across multiple EVM compatible chains and recommendation is to store contract addresses to EVM chain specific address record field.

Can I use libraries from other name services that support .eth?

@unstoppabledomains/resolution removed ENS support as of December 2021. Other services tend not to support all ENS TLDs especially DNS based TLDs (.com, .net, etc) so we advise not to rely on these libraries resolving ENS names.

Our chain is not Rollup, but we have a ways to verify our state in Ethereum L1. Can we still integrate?

It would be possible If there is a lightclient that can verify the chain's state and data on Ethereum L1.

References and previous discussions