syshen

Posted on Feb 05, 2022Read on Mirror.xyz

ENS: Ethereum Name Service

在 blockchain 的世界裡,每個人的 identity 都會是一個位址,像是0x956f206BF42B6FCEacacBEb759Bc234921B55eCf,這是錢包的位址,這是一個 42 字元組成的 public key hash,基本上沒有人記得住這一長串字元,所以大部分遇到時都是用複製貼上,或者 QR Code scan 的方式來傳遞。

所以好像很自然,Name resolve service 就有存在的必要,像是 IP address 與 domain name 互查的 DNS 系統,在區塊鏈中也有套類似的架構,稱之為 ENS: Ethereum Name Service。

你可以為你的錢包位址登記一個好記的名字,像是 be-rich.eth ,如果去反查這個名字就會是 0x956f206BF42B6FCEacacBEb759Bc234921B55eCf

ENS 有兩大智能合約所組成,分別是 Registry (EIP-137) 跟 Resolver,Resolver 也支援好幾種不同的查詢方式,也包含一般的網路域名,還有 TXT Record。

來了解一下它怎麼運作的:

我先到 ens.domain 買了一個域名 be-rich.eth,隨後就會透過我的 Metamask 錢包與合約互動。

註冊通常很快,約一分鐘完成,隨後我們打開 etherscan 來看看他做了哪些動作。

這是該筆交易。

首先你會看到交易紀錄,它先 Mint 了一顆 Token ,再把這顆 Token 的 Owner 轉到我的位址下。

然後裡面包含兩次的 Token 轉移,一次是從 0x0 轉到 ENS 的 Registry ,一次是從 ENS Registry 轉移到我的位址。

Token 是符合 ERC-721 規範,也就是說它是顆 NFT。

所以在我的 Opensea 下也可以看到這顆 Token


再來看看註冊域名時,它怎麼呼叫合約的:

看來是呼叫合約中的 registerWithConfig() 函式,帶的參數有包含名稱 (be-rich.eth),owner 位址(也就是我的錢包位址),duration 為 31556952 也就是比 365 天多一點點 (應該是為了處理閏年),設定的 resolver 位址為 0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41,這個是 ENS 的 Public Resolver 2 的合約位址。

ENS 有個特色,.eth 屬於根域名,假如你註冊個 apple.eth ,未來你可以自行發行子域名,例如 steve.apple.eth ,你可以有自己的 Resolver 來反查子域名,不必都透過公用的 resolver,所以在購買 ENS token 時,可以指定 Resolver 合約的位址,而你要寫 Resolver 也很簡單,只要符合它的定義就好。 不過想單然而,因為有這樣的設計,現在就會有很多人搶著註冊有名的域名來當蟑螂,就跟 DNS 一樣,所以未來一些大公司真的開始想進入 blockchain 領域時,可能要準備一筆錢來買域名了。

ENS 合約內並不是儲存完整的域名,而是儲存域名的 Hash,它稱之為 namehash。它的概念是以 dot 為區隔拆出各個名稱 (label),然後去作 hash,例如 be-rich.eth 可以拆出兩個 label 分別是 be-rich 以及 eth,namehash 的算法如下:

namehash([]) = 0x0000000000000000000000000000000000000000000000000000000000000000
namehash([label, …]) = keccak256(namehash(…), keccak256(label))

namehash 再去轉換成一個 32bytes 的 unsighted int 作為 tokenID,合約裡儲存的就是 tokenID 與 owner address 間的 mapping。

要反查名稱時,你可以自己寫合約來查詢,也可以透過 ENS 官方提供的 Libraries 來查詢。以 ensjs Javascript library 來作的話就像這樣:

var address = await ens.name('be-rich.eth').getAddress();

原理上也是一樣,透過域名取得 namehash,然後由 namehash 先取得 Resolver,再跟 Resolver 詢問位址。

也可以透過智能合約來查詢

abstract contract ENS {
    function resolver(bytes32 node) public virtual view returns (Resolver);
}

abstract contract Resolver {
    function addr(bytes32 node) public virtual view returns (address);
}

contract MyContract {
    // Same address for Mainet, Ropsten, Rinkerby, Gorli and other networks;
    ENS ens = ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);

    function resolve(bytes32 node) public view returns(address) {
        Resolver resolver = ens.resolver(node);
        return resolver.addr(node);
    }
}

有這個域名能幹嘛? 目前多數錢包都有支援 ENS,所以當你在做交易時,就不再需要使用錢包位址這麼難記的字串,直接請對方輸入你的域名就好,例如在 metamask 中,你只需要傳送 ETH 到 be-rich.eth 就可以轉進到我的錢包中了。

不過就像目前 Internet ,域名蟑螂是個嚴重的問題,在 ENS 中會更嚴重。想像一下,如果我註冊一個 paypal.eth,是否就機會偽裝成 paypal 到處去跟小白收款,或者註冊 google.eth、apple.eth,就可以等著大公司來跟我收購這些域名,因為這些 Trademark 都是在區塊鏈出來之前就已經存在了,但是在區塊鏈中違反 trademark 對這些蟑螂來說無傷痛癢。而 ENS 唯一能做的是透過每年 renew 的費用來增加蟑螂的成本,但對於資本雄厚,或者已經擁有高價值 trademark 的域名來說,似乎無傷痛癢。

EthereumENS