ENS-over-DNS services like eth.limo are amazing, eg. vitalik.eth.limo, however there is a collision issue with some names.
There are names that work perfectly with DNS ("vitalik.eth"
), names that donβt work with DNS ("-x-.eth"
or "xn--π©.eth"
), and names that can be converted to Punycode ("π©.eth"
β "xn--ls8h.eth"
).
Most browsers use UTS-46 (IDNA 2003, Transitional=True) on URL input, but not all browsers work the same. Most Punycode libraries follow the same conventions.
The following (2) names are distinct in ENS:
-
π΅βπ«π΅βπ«π΅βπ« 1F635 200D 1F4AB 1F635 200D 1F4AB 1F635 200D 1F4AB
(3 sets ofπ΅+ZWJ+π«
) -
π΅π«π΅π«π΅π« 1F635 1F4AB 1F635 1F4AB 1F635 1F4AB
(6 separate emoji)
However, most browsers and Punycode implementations translate both names to xn--ns8haa78mbab
, resulting in a collision.
For reference, under my potential ENS normalization spec, ZWJ may only appear in emoji sequences.
There should be a mechanism to determine if an ENS name can work with DNS (verbatim, punycoded, or invalid). If it does, it should provide the correct DNS translation.
- For example, I added this functionality to my resolver demo:
Because thereβs no way to determine the preferred name for a collision, names that have collisions should not be reachable. I see the following solutions:
-
Do nothing. All names can be addressed via Punycode. Tell users not to trust URL input translation for names with ZWJ sequences or deviation characters. Users who want to ensure DNS functionality should register the IDNA-mangled version(s) of their name.
-
Do not resolve names that could potentially collide:
- Do not resolve any name that contains a ZWJ sequence (where the ZWJ are optional.) In the above example,
π΅βπ« 1F635 200D 1F4AB
is valid RGI emoji sequence. Therefore, do not resolve a name containing1F635 1F4AB
or1F635 200D 1F4AB
. - I donβt know what to do about the deviations
ss <=> Γ
andΟ <=> Ο
. Browsers transform these differently too (Firefox is leavesΓ
alone, Chrome maps toss
). It seems unwise to ban every ENS name that containsss
from DNS. If you only ban the deviations, thenjeΓ.eth
might go tojess.eth
in certain browsers without warning.
- Do not resolve any name that contains a ZWJ sequence (where the ZWJ are optional.) In the above example,
-
Maintain a database of actively registered collisions (tracking registrations, renews, and expiration). Unfortunately, this would mean your DNS/URL would randomly break if someone registers a collision.
-
Encourage the owner to purchase all permutations of their name (if they really want DNS functionality but have a name with collision possibilities) and then check for common owner on resolution (unnecessarily complicated.)
-
Get first-class ENS support in browsers!
ENS names registered as Punycode literals (xn--*.eth
) should not be reachable from DNS.
Here are the list of current collisions:
// note: some collisions are Punycode literals
// escape notation: {HEX} -> \u{HEX}
[
["edelwei{DF}", "edelweiss"],
["weisswein", "wei{DF}wein"],
["xn--0ciaa", "{2728}{2728}{2728}"],
["xn--og8haa", "{1F308}{1F308}{1F308}"],
["{56E7}{56E7}{56E7}", "xn--8bsaa"],
["{1F635}{1F4AB}{1F635}{1F4AB}{1F635}{1F4AB}", "{1F635}{200D}{1F4AB}{1F635}{200D}{1F4AB}{1F635}{200D}{1F4AB}"],
["xn--ki8haa", "{1F34A}{1F34A}{1F34A}"],
["{1F408}{2B1B}{1F408}{2B1B}{1F408}{2B1B}", "{1F408}{200D}{2B1B}{1F408}{200D}{2B1B}{1F408}{200D}{2B1B}"],
["{1F3F4}{200D}{2620}{1F3F4}{200D}{2620}{1F3F4}{200D}{2620}", "{1F3F4}{2620}{1F3F4}{2620}{1F3F4}{2620}"],
["{1F97A}{1F449}{1F448}", "xn--tp8hb001b"],
["{1F636}{1F32B}{1F636}{1F32B}{1F636}{1F32B}", "{1F636}{200D}{1F32B}{1F636}{200D}{1F32B}{1F636}{200D}{1F32B}"],
["nussbaumer", "nu{DF}baumer"],
["mnussbaumer", "mnu{DF}baumer"],
["{2764}{1F525}{2764}{1F525}{2764}{1F525}", "{2764}{200D}{1F525}{2764}{200D}{1F525}{2764}{200D}{1F525}"],
["{1F636}{200D}{1F32B}{1F636}{200D}{1F32B}", "{1F636}{1F32B}{1F636}{1F32B}"],
["xn--ms8ha18h", "{1F4AA}{1F60E}{1F4AA}"],
["{1F3F3}{200D}{1F308}{1F3F3}{200D}{1F308}{1F3F3}{200D}{1F308}", "{1F3F3}{1F308}{1F3F3}{1F308}{1F3F3}{1F308}"],
["{1F43B}{200D}{2744}{1F43B}{200D}{2744}{1F43B}{200D}{2744}", "{1F43B}{2744}{1F43B}{2744}{1F43B}{2744}"],
["{1F3F3}{200D}{26A7}{1F3F3}{200D}{26A7}{1F3F3}{200D}{26A7}", "{1F3F3}{26A7}{1F3F3}{26A7}{1F3F3}{26A7}"],
["weissbier", "wei{DF}bier"],
["{2764}{200D}{1F525}{2764}{200D}{1F525}", "{2764}{1F525}{2764}{1F525}"],
["gro{DF}mann", "grossmann"],
["fu{DF}ball", "fussball"]
]
Edit: I donβt think this is anything serious, but it popped up while thinking through some DNS stuff, and I figured I should make note of it.