DNS 是一种联合命名系统,更高级别的实体控制其下所有内容的可用性(例如.org 控制 ethereum.org 的可用性)。分散式 DNS 版本不会有此约束,并允许直接查找 ENS 中具有相关记录的任何域。
向后兼容性
不适用。
参考实现
DNS 解析器的参考实现如下:
pragmasolidity^0.7.4;import"../ResolverBase.sol";import"@ensdomains/dnssec-oracle/contracts/RRUtils.sol";abstractcontractDNSResolverisResolverBase{usingRRUtilsfor*;usingBytesUtilsforbytes;bytes4constantprivateDNS_RECORD_INTERFACE_ID=0xa8fa5682;bytes4constantprivateDNS_ZONE_INTERFACE_ID=0x5c47637c;// DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.
// 当给定节点/名称/资源的 RRSET 更新时,会发出 DNSRecordChanged 事件。
eventDNSRecordChanged(bytes32indexednode,bytesname,uint16resource,bytesrecord);// DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.
// 当给定节点/名称/资源的 RRSET 删除时,会发出 DNSRecordDeleted 事件。
eventDNSRecordDeleted(bytes32indexednode,bytesname,uint16resource);// DNSZoneCleared is emitted whenever a given node's zone information is cleared.
// 当给定节点的区域信息被清除时,会发出 DNSZoneCleared 事件。
eventDNSZoneCleared(bytes32indexednode);// DNSZonehashChanged is emitted whenever a given node's zone hash is updated.
// 当给定节点的区域哈希更新时,会发出 DNSZonehashChanged 事件。
eventDNSZonehashChanged(bytes32indexednode,byteslastzonehash,byteszonehash);// Zone hashes for the domains.
// 域的区域哈希。
// A zone hash is an ERC-1577 content hash in binary format that should point to a
// 区域哈希是以二进制格式的 ERC-1577 内容哈希,它应该指向一个
// resource containing a single zonefile.
// 包含单个区域文件的资源。
// node => contenthash
// 节点 => contenthash
mapping(bytes32=>bytes)privatezonehashes;// Version the mapping for each zone. This allows users who have lost
// 为每个区域版本化映射。这允许丢失了
// track of their entries to effectively delete an entire zone by bumping
// 他们的条目的跟踪的用户可以通过增加来有效地删除整个区域
// the version number.
// 版本号。
// node => version
// 节点 => 版本
mapping(bytes32=>uint256)privateversions;// The records themselves. Stored as binary RRSETs
// 记录本身。存储为二进制 RRSET
// node => version => name => resource => data
mapping(bytes32=>mapping(uint256=>mapping(bytes32=>mapping(uint16=>bytes))))privaterecords;// Count of number of entries for a given name. Required for DNS resolvers
// 给定名称的条目数计数。DNS 解析器需要
// when resolving wildcards.
// 在解析通配符时。
// node => version => name => number of records
mapping(bytes32=>mapping(uint256=>mapping(bytes32=>uint16)))privatenameEntriesCount;/**
* Set one or more DNS records. Records are supplied in wire-format.
* 设置一个或多个 DNS 记录。记录以 wire 格式提供。
* Records with the same node/name/resource must be supplied one after the
* 具有相同节点/名称/资源的记录必须一个接一个地提供
* other to ensure the data is updated correctly. For example, if the data
* 以确保数据已正确更新。例如,如果数据
* was supplied:
* 是提供的:
* a.example.com IN A 1.2.3.4
* a.example.com IN A 5.6.7.8
* www.example.com IN CNAME a.example.com.
* then this would store the two A records for a.example.com correctly as a
* 那么这将正确地将 a.example.com 的两个 A 记录存储为
* single RRSET, however if the data was supplied:
* 单个 RRSET,但是如果数据为
* a.example.com IN A 1.2.3.4
* www.example.com IN CNAME a.example.com.
* a.example.com IN A 5.6.7.8
* then this would store the first A record, the CNAME, then the second A
* 那么这将存储第一个 A 记录,CNAME,然后是第二个 A
* record which would overwrite the first.
* 记录,它将覆盖第一个记录。
*
* @param node the namehash of the node for which to set the records
* @param node 要设置记录的节点的 namehash
* @param data the DNS wire format records to set
* @param data 要设置的 DNS wire 格式记录
*/functionsetDNSRecords(bytes32node,bytescalldatadata)externalauthorised(node){uint16resource=0;uint256offset=0;bytesmemoryname;bytesmemoryvalue;bytes32nameHash;// Iterate over the data to add the resource records
// 迭代数据以添加资源记录
for(RRUtils.RRIteratormemoryiter=data.iterateRRs(0);!iter.done();iter.next()){if(resource==0){resource=iter.dnstype;name=iter.name();nameHash=keccak256(abi.encodePacked(name));value=bytes(iter.rdata());}else{bytesmemorynewName=iter.name();if(resource!=iter.dnstype||!name.equals(newName)){setDNSRRSet(node,name,resource,data,offset,iter.offset-offset,value.length==0);resource=iter.dnstype;offset=iter.offset;name=newName;nameHash=keccak256(name);value=bytes(iter.rdata());}}}if(name.length>0){setDNSRRSet(node,name,resource,data,offset,data.length-offset,value.length==0);}}/**
* Obtain a DNS record.
* 获取 DNS 记录。
* @param node the namehash of the node for which to fetch the record
* @param node 要获取记录的节点的 namehash
* @param name the keccak-256 hash of the fully-qualified name for which to fetch the record
* @param name 要获取记录的完全限定名称的 keccak-256 哈希
* @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types
* @param resource 资源的 ID,如 https://en.wikipedia.org/wiki/List_of_DNS_record_types 所示
* @return the DNS record in wire format if present, otherwise empty
* @return 如果存在,则返回 wire 格式的 DNS 记录,否则返回空
*/functiondnsRecord(bytes32node,bytes32name,uint16resource)publicviewreturns(bytesmemory){returnrecords[node][versions[node]][name][resource];}/**
* Check if a given node has records.
* 检查给定节点是否具有记录。
* @param node the namehash of the node for which to check the records
* @param node 要检查记录的节点的 namehash
* @param name the namehash of the node for which to check the records
* @param name 要检查记录的节点的 namehash
*/functionhasDNSRecords(bytes32node,bytes32name)publicviewreturns(bool){return(nameEntriesCount[node][versions[node]][name]!=0);}/**
* Clear all information for a DNS zone.
* 清除 DNS 区域的所有信息。
* @param node the namehash of the node for which to clear the zone
* @param node 要清除区域的节点的 namehash
*/functionclearDNSZone(bytes32node)publicauthorised(node){versions[node]++;emitDNSZoneCleared(node);}/**
* setZonehash sets the hash for the zone.
* setZonehash 设置区域的哈希。
* May only be called by the owner of that node in the ENS registry.
* 只能由 ENS 注册表中该节点的所有者调用。
* @param node The node to update.
* @param node 要更新的节点。
* @param hash The zonehash to set
* @param hash 要设置的 区域哈希
*/functionsetZonehash(bytes32node,bytescalldatahash)externalauthorised(node){bytesmemoryoldhash=zonehashes[node];zonehashes[node]=hash;emitDNSZonehashChanged(node,oldhash,hash);}/**
* zonehash obtains the hash for the zone.
* zonehash 获取区域的哈希。
* @param node The ENS node to query.
* @param node 要查询的 ENS 节点。
* @return The associated contenthash.
* @return 关联的 contenthash。
*/functionzonehash(bytes32node)externalviewreturns(bytesmemory){returnzonehashes[node];}functionsupportsInterface(bytes4interfaceID)virtualoverridepublicpurereturns(bool){returninterfaceID==DNS_RECORD_INTERFACE_ID||interfaceID==DNS_ZONE_INTERFACE_ID||super.supportsInterface(interfaceID);}functionsetDNSRRSet(bytes32node,bytesmemoryname,uint16resource,bytesmemorydata,uint256offset,uint256size,booldeleteRecord)private{uint256version=versions[node];bytes32nameHash=keccak256(name);bytesmemoryrrData=data.substring(offset,size);if(deleteRecord){if(records[node][version][nameHash][resource].length!=0){nameEntriesCount[node][version][nameHash]--;}delete(records[node][version][nameHash][resource]);emitDNSRecordDeleted(node,name,resource);}else{if(records[node][version][nameHash][resource].length==0){nameEntriesCount[node][version][nameHash]++;}records[node][version][nameHash][resource]=rrData;emitDNSRecordChanged(node,name,resource,rrData);}}}