🦄️🦄️🦄️

Posted on Sep 27, 2022Read on Mirror.xyz

关于 ENS 的键帽字符

背景知识

什么是键帽字符

键帽字符是一串数字 emoji,比如:

1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣0⃣️🔟#️⃣*️⃣

什么是完全合格的 emoji

起初,Unicode 字符中的 emoji 表情符号只有黑色。而随着 emoji 表情符号的逐渐发展,其中一些 emoji 开始有了彩色版本。然而,有些字体能支持显示完整的 emoji,有些字体不支持。这使同一个 emoji 在不同的平台上有了多种形式 。

以上资料引用自 这里

测试调研

完全合格的键帽字符

完全合格的键帽 1️⃣ 的 URI encode 后的结果是:

encodeURI('1️⃣')
'1%EF%B8%8F%E2%83%A3'

%EF%B8%8F变体选择器 ,意思是将它前面的字符以 emoji 的形式展示

%E2%83%A3结合封闭键帽 ,专用于隔离键帽 emoji

输入法生成的键帽字符

我用 mac 自带的输入法,拿到的 1⃣️ 的 URI encode 结果是:

encodeURI('1⃣️')
'1%E2%83%A3%EF%B8%8F'

由上面的结论可知,发现输入法生成的 变体选择器结合封闭键帽 顺序是反的。自然两者也就不相等了:

'1⃣' === '1️⃣'
false

塞入多个变体选择器

然后再多塞几个 变体选择器 ,并与完全合格的键帽比较:

decodeURI('1%EF%B8%8F%E2%83%A3%EF%B8%8F')
'1️⃣️'
'1️⃣️' === '1️⃣'
false

结论: 可以一直塞多个 变体选择器 而不影响最终的视觉展示

twitter 搜索测试

在 twitter 上搜索 1️⃣2️⃣3️⃣.eth 的结果

下图的 1️⃣ 是塞了两个 变体选择器 的搜索结果,发现什么也搜不到:

https://twitter.com/search?q=1%EF%B8%8F%EF%B8%8F%E2%83%A32%EF%B8%8F%E2%83%A33%EF%B8%8F%E2%83%A3.eth&src=typed_query&f=top

下图的 1️⃣ 就是完全合格的键帽 emoji 的 搜索结果:

https://twitter.com/search?q=1%EF%B8%8F%E2%83%A32%EF%B8%8F%E2%83%A33%EF%B8%8F%E2%83%A3.eth&src=typed_query&f=top

浏览器地址栏显示测试

chrome

https://www.emojiall.com/zh-hans/emoji/0%EF%B8%8F%E2%83%A3

https://www.emojiall.com/zh-hans/emoji/0%E2%83%A3

safari

结论: 要想在浏览器地址栏里优雅地显示 emoji,则需要使用不合格表示法,即干掉里面的 变体选择器

引申

那如果我们再用不合格的键帽在 twitter 上搜索呢,居然也能搜索出结果来:

https://twitter.com/search?q=1%E2%83%A32%E2%83%A33%E2%83%A3.eth&src=typed_query&f=top

但搜索出的内容是不一样的,因为我复制了不合格搜索结果的 1⃣2⃣3⃣.eth 与完全合格的 1️⃣2️⃣3️⃣.eth 是不一样的:

'1⃣2⃣3⃣.eth' === '1️⃣2️⃣3️⃣.eth'
false

也就是说,上面的场景下,在 twitter 里面显示的 1️⃣2️⃣3️⃣.eth 和 1️⃣2️⃣3️⃣.eth 是两种不一样的 ENS,只是视觉上是一样的而已

ens domain

无论搜索的是 1️⃣2️⃣3️⃣.eth 还是 1⃣2⃣3⃣.eth 展示的结果都是:https://app.ens.domains/name/1%E2%83%A32%E2%83%A33%E2%83%A3.eth/details

结论: 所以从 ens.domain 上注册的都是不合格的键帽,但反而却被 ens 官方强制扶正,认定为这种兼容性最差的键帽格式才是正统。详情参见 1️⃣2️⃣3️⃣.eth 的注册交易

opensea

只能搜索到不合格的 1⃣2⃣3⃣.eth ,而且用的字体正好是不兼容这种不合格的 emoji 的,所以显示很奇怪:

etherscan

目前两种 NFT 都已被注册

完全合格的 1️⃣2️⃣3️⃣.ethhttps://etherscan.io/nft/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85/65500681650595787883240792993076550848892653777790200001583287977258956136539

不合格的 1⃣2⃣3⃣.ethhttps://etherscan.io/nft/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85/33324163493671772743162099004136274185101712000141871054933792093926554750217

有趣的是细究这笔完全合格的 1️⃣2️⃣3️⃣.eth 注册 交易,会发现调用者显然也是直接与合约交互的,因为在 ens.domain 里面注册的话只会调用 registerWithConfig ,而这笔交易为了省点 gas 费直接使用的 register 接口(应该是个比较熟悉 ENS 的程序员)。

结论

可惜啊,opensea/nftgo/nftscan/metamask 等众多 dapp 都没有自建数据库,都是直接使用的 ensdomain 的接口,在这个中心化接口里将兼容性最差的 1⃣2⃣3⃣.eth 给强行规定为正版,兼容性更好的 1️⃣2️⃣3️⃣.eth 则被成了盗版,非常 web3 了。

猜测 ENS 选择兼容性最差的旧版的 emoji 应该是完全从域名的角度考虑(而不是从账户名角度)的,因为兼容性最好的键帽 emoji (包含在 2016 年的 emoji 3.0 中)确实是无法与 punycode(2003 年的 rfc3492) 互转的。

这个带来的问题就是,以后会出现两个在聊天窗口里长得一模一样的带 emoji 的链接,点进去却发现是完全不一样的网站内容,极其容易导致视觉欺骗的钓鱼案例。这反而与 IDNA 标准的初衷违背

ENS