ENS 域名注册表智能合约(ENSRegistry.sol)解析
ENS 注册表合约是 ENS 系统中的核心合约,了解这个合约可以敲开我们理解 ENS 域名系统的大门。
打开下面的折叠区域可以查看用 Solidity 语言编写的详细代码。当前部署在以太坊中的 ENS 注册表合约是用 LLL 语言编写的(ENS 最早采用 LLL 语言的原因),但因为 LLL 语言的可读性很差,于是 ENS 官方团队公布了用 Solidity 语言实现的 ENS 注册表合约。
1 pragma solidity ^0.5.0; 2 3 import "./ENS.sol"; 4 5 contract ENSRegistry is ENS { 6 struct Record { 7 address owner; 8 address resolver; 9 uint64 ttl; 10 } 11 12 mapping (bytes32 => Record) records; 13 14 modifier only_owner(bytes32 node) { 15 require(records[node].owner == msg.sender); 16 _; 17 } 18 19 constructor() public { 20 records[0x0].owner = msg.sender; 21 } 22 23 function setOwner(bytes32 node, address owner) external only_owner(node) { 24 emit Transfer(node, owner); 25 records[node].owner = owner; 26 } 27 28 function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external only_owner(node) { 29 bytes32 subnode = keccak256(abi.encodePacked(node, label)); 30 emit NewOwner(node, label, owner); 31 records[subnode].owner = owner; 32 } 33 34 function setResolver(bytes32 node, address resolver) external only_owner(node) { 35 emit NewResolver(node, resolver); 36 records[node].resolver = resolver; 37 } 38 39 function setTTL(bytes32 node, uint64 ttl) external only_owner(node) { 40 emit NewTTL(node, ttl); 41 records[node].ttl = ttl; 42 } 43 44 function owner(bytes32 node) external view returns (address) { 45 return records[node].owner; 46 } 47 48 function resolver(bytes32 node) external view returns (address) { 49 return records[node].resolver; 50 } 51 52 function ttl(bytes32 node) external view returns (uint64) { 53 return records[node].ttl; 54 } 55 56 }
下面我们来一步一步解析这个智能合约。
pragma solidity ^0.5.0;
这是 solidity 版本声明,0.5.0代表 solidity 版本,^ 号表示向上兼容。
import "./ENS.sol";
表示合约引用了 ENS.sol 合约。ENS.sol 合约是一个注册表接口合约,而 ENSRegistry.sol 合约包含着具体的注册表实现代码。
struct Record { address owner; address resolver; uint64 ttl; }
定义了 ENS 记录的结构。
字段 address 表示一个 ENS 域名的所有者地址。
字段 address 表示一个 ENS 域名的解析器地址。
字段 ttl 表示一个 ENS 域名的 TTL 值。
mapping (bytes32 => Record) records;
创建了一个名为 records 的映射类型,表示从节点到记录的映射。节点是指在 ENS 系统中用来标识域名的一个哈希值,节点的处理是 ENS 系统中的关键内容,有兴趣的可以进一步了解 ENS 域名处理。
modifier only_owner(bytes32 node) { require(records[node].owner == msg.sender); _; }
创建了一个函数修改器,用来限定那些只允许指定节点的所有者来执行的函数。
constructor() public { records[0x0].owner = msg.sender; }
合约构造器。合约部署时会将 ENS 域名根域的所有权赋予部署者。
function setOwner(bytes32 node, address owner) external only_owner(node) { emit Transfer(node, owner); records[node].owner = owner; }
setOwner 函数实现将一个节点的所有权转让给另一个地址,该函数只能由该节点当前的所有者来调用。
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external only_owner(node) { bytes32 subnode = keccak256(abi.encodePacked(node, label)); emit NewOwner(node, label, owner); records[subnode].owner = owner; }
setSubnodeOwner 函数将一个子节点的所有权转让给一个新的地址,该函数只能由其父节点的所有者来调用。
function setResolver(bytes32 node, address resolver) external only_owner(node) { emit NewResolver(node, resolver); records[node].resolver = resolver; }
setResolver 函数用来设置指定节点的解析器地址,该函数只能由这个节点的所有者来调用。
function setTTL(bytes32 node, uint64 ttl) external only_owner(node) { emit NewTTL(node, ttl); records[node].ttl = ttl; }
setTTL 函数用来设置指定节点的 TTL,该函数只能由这个节点的所有者来调用。
function owner(bytes32 node) external view returns (address) { return records[node].owner; }
owner 函数用来获取指定节点的所有者地址。
function resolver(bytes32 node) external view returns (address) { return records[node].resolver; }
resolver 函数用来获取指定节点的解析器地址。
function ttl(bytes32 node) external view returns (uint64) { return records[node].ttl; }
ttl 函数用来获取指定节点的 TTL 值。
以上就是 ENSRegistry.sol 合约的全部代码,这个合约自部署到以太坊主网来以来,一直没有变更过,相当于 ENS 的 “户籍系统” ,它记录着所有的 ENS 域名的所有者、解析器等 “户口信息” 。
ENS 在未来会有更加广泛的应用。如果您对 ENS 域名有兴趣,一定要在下面留言与我交流。