Update on gasless DNSSEC implementation

This is going to be awesome.


:saluting_face: Beta testers standing by


I would be happy to be one of the testers on a testnet.


Is there any docs/ENSIP for this?? :pray:


@nick.eth @gregskril Is the code for the DNSSec Oracle gateway (at https://dnssec-oracle.ens.domains/) open source? I can’t seem to find it.

1 Like

Yep! Here it is


I got a heap




Subdomains like australia.bilby.org/news should be gasless for sure

Maybe not though. They’re accounts created and the DAO is not responsible for gwei fractions imposed on transactions such as account creation

But tagging gwei - say colored coins - that’s a very cool concept too.

Excuse me, this was rushed and so forth

1 Like

how’s this going?

It’s coming along - a version is deployed to Sepolia testnet and the team is working through the last few bugs. I’ve written a quick doc on how it works and how you can test it here.


Is it finally compatible with IDNA domains?
@ENSPunks.eth was trying to import his short emoji domains for long time but current DNSSEC oracles/contracts & API used by UI couldn’t handle that…

@raffy saving us from extra hard work as always… :vulcan_salute:


No; that will require someone to implement punycode decoding in Solidity, which hasn’t been done yet.

If anyone wants to pick that up (@raffy?), there’s definitely room to pay for it.


That contract does decode, but it was just a proof-of-concept. I can clean it up and add tests, etc.

From what I remember, I wasn’t sure what the exact signature should be:

function decode(string memory puny) public pure returns (string memory uni) { or revert?

1 Like

Yes, that seems reasonable.

1 Like

I deployed a demo on base: Punycode Decoder

I tested it on all known ENS registrations.

The original version seemed reasonably efficient so I didn’t do any additional optimizations. The gas is approximately 500 gas/codepoint, where the worst case is likely 56 emoji Unicode codepoints. A typical non-ASCII label requires ~20000 gas to decode.

It’s unclear if we can assume that all IDNs are valid so it might be smart to confirm that the domain round-trips (puny → uni → puny) and that norm(uni) == uni before registration.

For IDNA 2008 compatibility, the only issue is the (7) mapped Arabic numerals. Either we need to disallow this case or do the mapping when decoding the punycode.

I think these are the changes for DNSRegistar.sol:

L141:  labelHash = keccak256(Punycode.decode(name, 1, labelLen));
L184:  bytes32 label = keccak256(Punycode.decode(domain, offset + 1, len));

Outstanding work!

The former would require a punycode encoder, which would be more work, as well as additional gas overhead. The latter would require implementing onchain normalization, which would be valuable to have but again, have substantial gas cost.

I’m personally in favor of omitting both checks based on my understanding of punycode and IDNA, but I’m very open to being persuaded otherwise. With optimistic DNSSEC, of course, gas costs become somewhat more academic in any case.

In fact - with optimistic dnssec, we need a punycode encoder, not decoder, since we’re given the unicode name and need to decode it to look it up in DNS!

Up for more work, Raffy? :grin:


Oh, I just meant they could be checked client-side (in js) before doing the transaction.

ENSIP-1 used IDNA 2003. ENSIP-15 uses 2003 too (because 2008 removes all emoji and disallows ZWJ.) AFAIK web2 registrars use both 2003 and 2008. ENSIP-15 should be compatible for everything registered that normalizes except those 7 Arabic Numerals, since a 2003 and 2008 numeral normalizes to the same thing. I’ll look around and see if I can find some examples.

I added encode() to the library and did some gas optimization to decode(). There’s one more obvious optimization (removing a uint32 array from the encoder). I also improved the API so you can encode/decode from a (ptr, len) and avoid a copy if no coding is required (eg. ASCII).

string memory s = "abc.xn--ls8h.com";
uint256 src;
assembly { src := add(s, 32) }
(uint256 dst, uint256 len) = Punycode.decode(src + 4, 8); // "xn--ls8h"
console2.log(len); // 4 bytes
assembly { s := sub(dst, 32) }
console2.log(s); // "💩"
bytes32 h;
assembly { h := keccak256(dst, len) }
console2.logBytes32(h); // 0xba967c160905ade030f84952644a963994eeaed3881a6b8a4e9c8cbe452ad7a2

encode() is approximately 2000 gas/codepoint but it varies. Non-ASCII registered labels seem to be 20-50k but over 100k is possible for repeated insertions.

encode() never reverts.


Good to see! Encode gas usage is less important, since it would always be invoked as part of a CCIP-Read request.


Congrats on getting this set up!! It’s very cool.

I’m not really in the know on what’s cooking but I’m assuming every platform with an ENS integration has to do some sort of upgrade to resolve these gaslessly imported names? For example, they do not resolve on almost every platform.

Coinbase mobile wallet app - .eth and onchains dns imports yes / gasless dns imports no

Coinbase desktop app - .eth and onchains dns imports yes / gasless dns imports no

Coinbase.com - .eth yes / onchain dns imports and gasless dns imports no

Rainbow mobile wallet app - .eth yes / onchain dns imports and gasless dns imports no

Farcaster - .eth yes / onchain dns imports and gasless dns imports no

Metamask mobile wallet app - .eth and onchains dns imports yes / gasless dns imports no

OpenSea - has stopped resolving all ens names entirely

PayPal crypto wallet - no ens name recognition

Metamask desktop app - .eth, onchain and gasless dns imports yes

I’m assuming there is a plan in the works to get wallets and platforms to resolve everything. In the meantime perhaps I jumped the gun telling people to try this gasless dns feature out since too many come back to me to say that it does not resolve in whatever app they’re using and move on disappointed. That’s probably my bad. I guess I’m surprised by how fragmented it all is.

  • I went in an added a line about Rainbow and Farcaster after the fact. DNS names in ENS are almost universally ignored by the largest apps, even the onchain ones that have been in use for years.

No. Platforms needed to update to support CCIP-Read and wildcard resolution, which was launched some time ago. The only reason a CCIP-Read based .eth name would work but a gasless DNSSEC name would not is if the wallet has an allowlist of ENS TLDs, in which case that needs to be removed.