ENS

ens的注冊(cè),與反向解析 (以文章時(shí)間的ens網(wǎng)站注冊(cè)和解析地址為例)
ETHRegistrarController: 0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5
BaseRegistrarImplementation(域名nft) :0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85
ENSRegistryWithFallback(ens):0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
ReverseRegistrar:0x084b1c3C81545d370f3634392De611CaaBFf8148
DefaultReverseResolver:0xA2C122BE93b0074270ebeE7f6b7292C7deB45047
PublicResolver:0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41
注冊(cè)
用戶 -> ETHRegistrarController -> makeCommitmentWithConfig(string memory name, address owner, bytes32 secret, address resolver, address addr)查詢不需要gas
用戶 -> commit(bytes32 commitment) public commit上一步的返回值
用戶 -> registerWithConfig 注冊(cè)

 function registerWithConfig(string memory name, address owner, uint duration, bytes32 secret, address resolver, address addr) public payable {
        bytes32 commitment = makeCommitmentWithConfig(name, owner, secret, resolver, addr);
        uint cost = _consumeCommitment(name, duration, commitment); //驗(yàn)證一下時(shí)間和域名是否被注冊(cè) 獲取需要支付的eth

        bytes32 label = keccak256(bytes(name));
        uint256 tokenId = uint256(label); //tokenId 是名字的hash

        uint expires;
        if(resolver != address(0)) {
            // Set this contract as the (temporary) owner, giving it
            // permission to set up the resolver.
            expires = base.register(tokenId, address(this), duration); // 1

            // The nodehash of this label
            bytes32 nodehash = keccak256(abi.encodePacked(base.baseNode(), label));

            // Set the resolver
            base.ens().setResolver(nodehash, resolver); // 2

            // Configure the resolver
            if (addr != address(0)) {
                Resolver(resolver).setAddr(nodehash, addr); // 3
            }

            // Now transfer full ownership to the expeceted owner
            base.reclaim(tokenId, owner); //4
            base.transferFrom(address(this), owner, tokenId); //把域名nft轉(zhuǎn)移給用戶
        } else {
            require(addr == address(0));
            expires = base.register(tokenId, owner, duration);
        }

        emit NameRegistered(name, label, owner, cost, expires);

        // Refund any extra payment
        if(msg.value > cost) {
            msg.sender.transfer(msg.value - cost); //退錢
        }
    }

1 BaseRegistrarImplementation -> register

function register(uint256 id, address owner, uint duration) external returns(uint) {
      return _register(id, owner, duration, true);
    }
function available(uint256 id) public view returns(bool) {
        // Not available if it's registered here or in its grace period.
        return expiries[id] + GRACE_PERIOD < now;
}
function _register(uint256 id, address owner, uint duration, bool updateRegistry) internal live onlyController returns(uint) { //owner 是 controller 合約
        require(available(id)); //
        require(now + duration + GRACE_PERIOD > now + GRACE_PERIOD); // Prevent future overflow

        expiries[id] = now + duration;
        if(_exists(id)) {
            // Name was previously owned, and expired
            _burn(id);
        }
        _mint(owner, id);  //mint 域名nft
        if(updateRegistry) {// baseNode The namehash of the TLD this registrar owns (eg, .eth) 也就是以.eth結(jié)尾
            ens.setSubnodeOwner(baseNode, bytes32(id), owner); 1.1
        }

        emit NameRegistered(id, owner, now + duration);

        return now + duration;
    }

1.1 ens -> setSubnodeOwner 有權(quán)限限制 require(owner == msg.sender || operators[owner][msg.sender]); 調(diào)用者被授權(quán)或者是basenode的所有者

    function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public authorised(node) returns(bytes32) {
        bytes32 subnode = keccak256(abi.encodePacked(node, label));
        _setOwner(subnode, owner);
        emit NewOwner(node, label, owner);
        return subnode;
    }

2 ens -> setResolver 設(shè)置正向解析器 有權(quán)限限制 require(owner == msg.sender || operators[owner][msg.sender]); 調(diào)用者被授權(quán)或者是basenode的所有者

 function setResolver(bytes32 node, address resolver) public authorised(node) { //resolver 是由用戶注冊(cè)時(shí)填的  可以自己定制 
        emit NewResolver(node, resolver);
        records[node].resolver = resolver;
    }

3 PublicResolver -> setAddr 設(shè)置域名解析出來(lái)對(duì)應(yīng)的地址 由方法addr(bytes32 node)獲取

 function setAddr(bytes32 node, uint coinType, bytes memory a) public authorised(node) {
        emit AddressChanged(node, coinType, a);
        if(coinType == COIN_TYPE_ETH) {
            emit AddrChanged(node, bytesToAddress(a));
        }
        _addresses[node][coinType] = a;
    }

4 BaseRegistrarImplementation -> reclaim //把node的owner權(quán)限移交給用戶

    function reclaim(uint256 id, address owner) external live { //owner 為用戶填入的注冊(cè)域名所有者
        require(_isApprovedOrOwner(msg.sender, id));
        ens.setSubnodeOwner(baseNode, bytes32(id), owner); //參照 1.1
    }

node的生成 bytes32 subnode = keccak256(abi.encodePacked(node, label));
域名的注冊(cè)和正向解析完成

反向解析,反向解析類似給地址設(shè)置昵稱搜贤,當(dāng)前合約并不限制昵稱必須是域名钓猬,但是ens設(shè)置反向解析時(shí)前端有限制裆针。也就是可以跳過(guò)前端給你的地址設(shè)置任意昵稱拓哺,我在rinkeby設(shè)置后在gnosissafe可以正常顯示 比如我給我地址設(shè)置反向解析為aaa.btc


1653034133(1).png

ReverseRegistrar -> setName

function claimWithResolver(address owner, address resolver) public returns (bytes32) { //owner 為 ReverseRegistrar  這里說(shuō)明這個(gè)子節(jié)點(diǎn)的owner權(quán)限為ReverseRegistrar
        bytes32 label = sha3HexAddress(msg.sender);
        bytes32 node = keccak256(abi.encodePacked(ADDR_REVERSE_NODE, label));
        address currentOwner = ens.owner(node);

        // Update the resolver if required
        if (resolver != address(0x0) && resolver != ens.resolver(node)) {
            // Transfer the name to us first if it's not already
            if (currentOwner != address(this)) {
//ADDR_REVERSE_NODE  = namehash('addr.reverse')
                ens.setSubnodeOwner(ADDR_REVERSE_NODE, label, address(this)); //參照1.1
                currentOwner = address(this);
            }
            ens.setResolver(node, resolver);
        }

        // Update the owner if required
        if (currentOwner != owner) {
            ens.setSubnodeOwner(ADDR_REVERSE_NODE, label, owner);
        }

        return node;
    }
    function setName(string memory name) public returns (bytes32) {
        bytes32 node = claimWithResolver(address(this), address(defaultResolver));
        defaultResolver.setName(node, name); //5
        return node;
    }

5 DefaultReverseResolver -> setName

    function setName(bytes32 node, string memory _name) public onlyOwner(node) {
        name[node] = _name;
    }

根據(jù)地址獲取昵稱 mapping (bytes32 => string) public name; =》 name(node) node 可以根據(jù)地址算出來(lái)

 bytes32 label = sha3HexAddress(msg.sender); //msg.sender -> 地址
 bytes32 node = keccak256(abi.encodePacked(ADDR_REVERSE_NODE, label));

以上馒吴!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扎运,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子饮戳,更是在濱河造成了極大的恐慌豪治,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扯罐,死亡現(xiàn)場(chǎng)離奇詭異负拟,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)篮赢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門齿椅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人启泣,你說(shuō)我怎么就攤上這事涣脚。” “怎么了寥茫?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵遣蚀,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我纱耻,道長(zhǎng)芭梯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任弄喘,我火速辦了婚禮玖喘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蘑志。我一直安慰自己累奈,他們只是感情好贬派,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澎媒,像睡著了一般搞乏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上戒努,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天请敦,我揣著相機(jī)與錄音,去河邊找鬼储玫。 笑死侍筛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缘缚。 我是一名探鬼主播勾笆,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼敌蚜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼桥滨!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起弛车,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤齐媒,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后纷跛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喻括,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年贫奠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唬血。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡唤崭,死狀恐怖拷恨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谢肾,我是刑警寧澤腕侄,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站芦疏,受9級(jí)特大地震影響冕杠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酸茴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一分预、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薪捍,春花似錦笼痹、人聲如沸魁淳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)界逛。三九已至,卻和暖如春纺座,著一層夾襖步出監(jiān)牢的瞬間息拜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工净响, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留少欺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓馋贤,卻偏偏與公主長(zhǎng)得像赞别,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子配乓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容