ENS

ens的注册,与反向解析 (以文章时间的ens网站注册和解析地址为例)
ETHRegistrarController: 0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5
BaseRegistrarImplementation(域名nft) :0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85
ENSRegistryWithFallback(ens):0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
ReverseRegistrar:0x084b1c3C81545d370f3634392De611CaaBFf8148
DefaultReverseResolver:0xA2C122BE93b0074270ebeE7f6b7292C7deB45047
PublicResolver:0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41
注册
用户 -> ETHRegistrarController -> makeCommitmentWithConfig(string memory name, address owner, bytes32 secret, address resolver, address addr)查询不需要gas
用户 -> commit(bytes32 commitment) public commit上一步的返回值
用户 -> registerWithConfig 注册

 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); //验证一下时间和域名是否被注册 获取需要支付的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转移给用户
        } 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结尾
            ens.setSubnodeOwner(baseNode, bytes32(id), owner); 1.1
        }

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

        return now + duration;
    }

1.1 ens -> setSubnodeOwner 有权限限制 require(owner == msg.sender || operators[owner][msg.sender]); 调用者被授权或者是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 设置正向解析器 有权限限制 require(owner == msg.sender || operators[owner][msg.sender]); 调用者被授权或者是basenode的所有者

 function setResolver(bytes32 node, address resolver) public authorised(node) { //resolver 是由用户注册时填的  可以自己定制 
        emit NewResolver(node, resolver);
        records[node].resolver = resolver;
    }

3 PublicResolver -> setAddr 设置域名解析出来对应的地址 由方法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权限移交给用户

    function reclaim(uint256 id, address owner) external live { //owner 为用户填入的注册域名所有者
        require(_isApprovedOrOwner(msg.sender, id));
        ens.setSubnodeOwner(baseNode, bytes32(id), owner); //参照 1.1
    }

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

反向解析,反向解析类似给地址设置昵称,当前合约并不限制昵称必须是域名,但是ens设置反向解析时前端有限制。也就是可以跳过前端给你的地址设置任意昵称,我在rinkeby设置后在gnosissafe可以正常显示 比如我给我地址设置反向解析为aaa.btc


1653034133(1).png

ReverseRegistrar -> setName

function claimWithResolver(address owner, address resolver) public returns (bytes32) { //owner 为 ReverseRegistrar  这里说明这个子节点的owner权限为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;
    }

根据地址获取昵称 mapping (bytes32 => string) public name; =》 name(node) node 可以根据地址算出来

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

以上!

你可能感兴趣的:(ENS)