ethers.js icon indicating copy to clipboard operation
ethers.js copied to clipboard

ENSIP-10 Reverse Resolution

Open adraffy opened this issue 1 year ago • 5 comments

I added EnsResolver.getName(). At a glance, it looks like a lot of EnsResolver could be simplified with the latest CCIP-Read stuff in v6.

I used that to re-implement AbstractResolver.lookupAddress(). I made this process more strict, as I don't think it's correct to return null for some of those cases. If that is too big of a change, possibly, we could add a separate function, which is strict, and the old function could just squelch those errors like the original implementation.

I unearthed an unused error type ValueMismatchError and used that for the mismatch case where the addresses don't match. Not sure if that fits your use-case. Additionally, maybe this function should get a second argument, which only does the one-sided request, as that it also useful in certain circumstances, although the new error would expose both addresses.


I'm not exactly sure how your testing stuff works. I added the start of a test but commented it. I ran build-dist and then tested it with a different project.

For testing, I configured a simple CCIP-Read reverse name on goerli that round-trips correctly and then called the new lookup function.

import {ethers} from 'ethers from fresh build-dist';
let p = new ethers.InfuraProvider(5);
let name = await p.lookupAddress("0xb404Af9A235Be881335d8898B5B487dc9Cd5ed9D");
// "raffyraffy.eth"

This corresponds to raffyraffy.eth which as the image shows, correctly round trips.

image

And the reverse record b404af9a235be881335d8898b5b487dc9cd5ed9d.addr.reverse is both wildcard and offchain.

image


For reference, this was my initial implementation using ethers v6.

import {ethers} from 'https://cdnjs.cloudflare.com/ajax/libs/ethers/6.11.0/ethers.js';
let provider = new ethers.InfuraProvider(5);
let name = 'b404af9a235be881335d8898b5b487dc9cd5ed9d.addr.reverse';
let node = ethers.namehash(name);
// get ensip-10 resolver
let {address: resolver} = await provider.getResolver(name);
// make ensip-10 contract stub
let contract = new ethers.Contract(resolver, [
	'function resolve(bytes,bytes) view returns (bytes)'
], provider);
// create call data
let abi = new ethers.Interface([
	'function name(bytes32) view returns (string)'
]);
// call resolve("name", name())
let request = abi.encodeFunctionData('name', [node]);
let response = await contract.resolve(
    ethers.dnsEncode(name, 255), 
    request, 
    {enableCcipRead: true}
);
let [primary] = abi.decodeFunctionResult('name', response);

adraffy avatar Mar 03 '24 09:03 adraffy

What can I do to help make this change? We're going to need CCIP-Read on .addr.reverse for upcoming ENS multichain functionality.

One issue is my null-behavior change to the lookupAddress() (see comment above)

The other is I'm not sure how your testing framework works or what you would allow. I think the ideal test would be like foundry-rs + blocksmith.js + ezccip.js and deploy a local testnet + ENS contracts + CCIP-server + and just test it. The simplest test is probably a fixed address contract on Sepolia that OffchainLookup reverts with a data: URL that is a valid CCIP-Response (so no CCIP-server is required.).

I'd be glad to supply an example repo with the first (ideal) solution or deploy a contract on Sepolia with the second (simplest) solution.

adraffy avatar Jun 12 '24 23:06 adraffy

Heya! Just checking if this is still relevant? Nick poked me about it and I’ll be doing some other ens updates soon. :)

ricmoo avatar Mar 19 '25 14:03 ricmoo

Keep in mind that it would be a major version change required to change from returning null in favour of using the planned (future major version) error. :)

ricmoo avatar Mar 19 '25 14:03 ricmoo

okay, I'll restore the original behavior

adraffy avatar Mar 19 '25 14:03 adraffy

Okay, I think I restored the old lookupAddress() null behavior.

I put a new getReverseName() static function on EnsResolver and updated lookupAddress() to follow ENSIP-19.

I'm not sure how to write the tests though, but I think the implementation is straightforward.

adraffy avatar Mar 24 '25 17:03 adraffy