编译器
0.8.17+commit.8df45f5f
文件 1 的 22:AddrResolver.sol
pragma solidity >=0.8.4;
import "../ResolverBase.sol";
import "./IAddrResolver.sol";
import "./IAddressResolver.sol";
abstract contract AddrResolver is
IAddrResolver,
IAddressResolver,
ResolverBase
{
uint256 private constant COIN_TYPE_ETH = 60;
mapping(uint64 => mapping(bytes32 => mapping(uint256 => bytes))) versionable_addresses;
function setAddr(
bytes32 node,
address a
) external virtual authorised(node) {
setAddr(node, COIN_TYPE_ETH, addressToBytes(a));
}
function addr(
bytes32 node
) public view virtual override returns (address payable) {
bytes memory a = addr(node, COIN_TYPE_ETH);
if (a.length == 0) {
return payable(0);
}
return bytesToAddress(a);
}
function setAddr(
bytes32 node,
uint256 coinType,
bytes memory a
) public virtual authorised(node) {
emit AddressChanged(node, coinType, a);
if (coinType == COIN_TYPE_ETH) {
emit AddrChanged(node, bytesToAddress(a));
}
versionable_addresses[recordVersions[node]][node][coinType] = a;
}
function addr(
bytes32 node,
uint256 coinType
) public view virtual override returns (bytes memory) {
return versionable_addresses[recordVersions[node]][node][coinType];
}
function supportsInterface(
bytes4 interfaceID
) public view virtual override returns (bool) {
return
interfaceID == type(IAddrResolver).interfaceId ||
interfaceID == type(IAddressResolver).interfaceId ||
super.supportsInterface(interfaceID);
}
function bytesToAddress(
bytes memory b
) internal pure returns (address payable a) {
require(b.length == 20);
assembly {
a := div(mload(add(b, 32)), exp(256, 12))
}
}
function addressToBytes(address a) internal pure returns (bytes memory b) {
b = new bytes(20);
assembly {
mstore(add(b, 32), mul(a, exp(256, 12)))
}
}
}
文件 2 的 22:Buffer.sol
pragma solidity ^0.8.4;
library Buffer {
struct buffer {
bytes buf;
uint capacity;
}
function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {
if (capacity % 32 != 0) {
capacity += 32 - (capacity % 32);
}
buf.capacity = capacity;
assembly {
let ptr := mload(0x40)
mstore(buf, ptr)
mstore(ptr, 0)
let fpm := add(32, add(ptr, capacity))
if lt(fpm, ptr) {
revert(0, 0)
}
mstore(0x40, fpm)
}
return buf;
}
function fromBytes(bytes memory b) internal pure returns(buffer memory) {
buffer memory buf;
buf.buf = b;
buf.capacity = b.length;
return buf;
}
function resize(buffer memory buf, uint capacity) private pure {
bytes memory oldbuf = buf.buf;
init(buf, capacity);
append(buf, oldbuf);
}
function truncate(buffer memory buf) internal pure returns (buffer memory) {
assembly {
let bufptr := mload(buf)
mstore(bufptr, 0)
}
return buf;
}
function append(buffer memory buf, bytes memory data, uint len) internal pure returns(buffer memory) {
require(len <= data.length);
uint off = buf.buf.length;
uint newCapacity = off + len;
if (newCapacity > buf.capacity) {
resize(buf, newCapacity * 2);
}
uint dest;
uint src;
assembly {
let bufptr := mload(buf)
let buflen := mload(bufptr)
dest := add(add(bufptr, 32), off)
if gt(newCapacity, buflen) {
mstore(bufptr, newCapacity)
}
src := add(data, 32)
}
for (; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
unchecked {
uint mask = (256 ** (32 - len)) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
return buf;
}
function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
return append(buf, data, data.length);
}
function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) {
uint off = buf.buf.length;
uint offPlusOne = off + 1;
if (off >= buf.capacity) {
resize(buf, offPlusOne * 2);
}
assembly {
let bufptr := mload(buf)
let dest := add(add(bufptr, off), 32)
mstore8(dest, data)
if gt(offPlusOne, mload(bufptr)) {
mstore(bufptr, offPlusOne)
}
}
return buf;
}
function append(buffer memory buf, bytes32 data, uint len) private pure returns(buffer memory) {
uint off = buf.buf.length;
uint newCapacity = len + off;
if (newCapacity > buf.capacity) {
resize(buf, newCapacity * 2);
}
unchecked {
uint mask = (256 ** len) - 1;
data = data >> (8 * (32 - len));
assembly {
let bufptr := mload(buf)
let dest := add(bufptr, newCapacity)
mstore(dest, or(and(mload(dest), not(mask)), data))
if gt(newCapacity, mload(bufptr)) {
mstore(bufptr, newCapacity)
}
}
}
return buf;
}
function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
return append(buf, bytes32(data), 20);
}
function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
return append(buf, data, 32);
}
function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) {
uint off = buf.buf.length;
uint newCapacity = len + off;
if (newCapacity > buf.capacity) {
resize(buf, newCapacity * 2);
}
uint mask = (256 ** len) - 1;
assembly {
let bufptr := mload(buf)
let dest := add(bufptr, newCapacity)
mstore(dest, or(and(mload(dest), not(mask)), data))
if gt(newCapacity, mload(bufptr)) {
mstore(bufptr, newCapacity)
}
}
return buf;
}
}
文件 3 的 22:BytesUtils.sol
pragma solidity ^0.8.4;
library BytesUtils {
error OffsetOutOfBoundsError(uint256 offset, uint256 length);
function keccak(
bytes memory self,
uint256 offset,
uint256 len
) internal pure returns (bytes32 ret) {
require(offset + len <= self.length);
assembly {
ret := keccak256(add(add(self, 32), offset), len)
}
}
function compare(
bytes memory self,
bytes memory other
) internal pure returns (int256) {
return compare(self, 0, self.length, other, 0, other.length);
}
function compare(
bytes memory self,
uint256 offset,
uint256 len,
bytes memory other,
uint256 otheroffset,
uint256 otherlen
) internal pure returns (int256) {
if (offset + len > self.length) {
revert OffsetOutOfBoundsError(offset + len, self.length);
}
if (otheroffset + otherlen > other.length) {
revert OffsetOutOfBoundsError(otheroffset + otherlen, other.length);
}
uint256 shortest = len;
if (otherlen < len) shortest = otherlen;
uint256 selfptr;
uint256 otherptr;
assembly {
selfptr := add(self, add(offset, 32))
otherptr := add(other, add(otheroffset, 32))
}
for (uint256 idx = 0; idx < shortest; idx += 32) {
uint256 a;
uint256 b;
assembly {
a := mload(selfptr)
b := mload(otherptr)
}
if (a != b) {
uint256 mask;
if (shortest - idx >= 32) {
mask = type(uint256).max;
} else {
mask = ~(2 ** (8 * (idx + 32 - shortest)) - 1);
}
int256 diff = int256(a & mask) - int256(b & mask);
if (diff != 0) return diff;
}
selfptr += 32;
otherptr += 32;
}
return int256(len) - int256(otherlen);
}
function equals(
bytes memory self,
uint256 offset,
bytes memory other,
uint256 otherOffset,
uint256 len
) internal pure returns (bool) {
return keccak(self, offset, len) == keccak(other, otherOffset, len);
}
function equals(
bytes memory self,
uint256 offset,
bytes memory other,
uint256 otherOffset
) internal pure returns (bool) {
return
keccak(self, offset, self.length - offset) ==
keccak(other, otherOffset, other.length - otherOffset);
}
function equals(
bytes memory self,
uint256 offset,
bytes memory other
) internal pure returns (bool) {
return
self.length == offset + other.length &&
equals(self, offset, other, 0, other.length);
}
function equals(
bytes memory self,
bytes memory other
) internal pure returns (bool) {
return
self.length == other.length &&
equals(self, 0, other, 0, self.length);
}
function readUint8(
bytes memory self,
uint256 idx
) internal pure returns (uint8 ret) {
return uint8(self[idx]);
}
function readUint16(
bytes memory self,
uint256 idx
) internal pure returns (uint16 ret) {
require(idx + 2 <= self.length);
assembly {
ret := and(mload(add(add(self, 2), idx)), 0xFFFF)
}
}
function readUint32(
bytes memory self,
uint256 idx
) internal pure returns (uint32 ret) {
require(idx + 4 <= self.length);
assembly {
ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF)
}
}
function readBytes32(
bytes memory self,
uint256 idx
) internal pure returns (bytes32 ret) {
require(idx + 32 <= self.length);
assembly {
ret := mload(add(add(self, 32), idx))
}
}
function readBytes20(
bytes memory self,
uint256 idx
) internal pure returns (bytes20 ret) {
require(idx + 20 <= self.length);
assembly {
ret := and(
mload(add(add(self, 32), idx)),
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000
)
}
}
function readBytesN(
bytes memory self,
uint256 idx,
uint256 len
) internal pure returns (bytes32 ret) {
require(len <= 32);
require(idx + len <= self.length);
assembly {
let mask := not(sub(exp(256, sub(32, len)), 1))
ret := and(mload(add(add(self, 32), idx)), mask)
}
}
function memcpy(uint256 dest, uint256 src, uint256 len) private pure {
for (; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
unchecked {
uint256 mask = (256 ** (32 - len)) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
}
function substring(
bytes memory self,
uint256 offset,
uint256 len
) internal pure returns (bytes memory) {
require(offset + len <= self.length);
bytes memory ret = new bytes(len);
uint256 dest;
uint256 src;
assembly {
dest := add(ret, 32)
src := add(add(self, 32), offset)
}
memcpy(dest, src, len);
return ret;
}
bytes constant base32HexTable =
hex"00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
function base32HexDecodeWord(
bytes memory self,
uint256 off,
uint256 len
) internal pure returns (bytes32) {
require(len <= 52);
uint256 ret = 0;
uint8 decoded;
for (uint256 i = 0; i < len; i++) {
bytes1 char = self[off + i];
require(char >= 0x30 && char <= 0x7A);
decoded = uint8(base32HexTable[uint256(uint8(char)) - 0x30]);
require(decoded <= 0x20);
if (i == len - 1) {
break;
}
ret = (ret << 5) | decoded;
}
uint256 bitlen = len * 5;
if (len % 8 == 0) {
ret = (ret << 5) | decoded;
} else if (len % 8 == 2) {
ret = (ret << 3) | (decoded >> 2);
bitlen -= 2;
} else if (len % 8 == 4) {
ret = (ret << 1) | (decoded >> 4);
bitlen -= 4;
} else if (len % 8 == 5) {
ret = (ret << 4) | (decoded >> 1);
bitlen -= 1;
} else if (len % 8 == 7) {
ret = (ret << 2) | (decoded >> 3);
bitlen -= 3;
} else {
revert();
}
return bytes32(ret << (256 - bitlen));
}
function find(
bytes memory self,
uint256 off,
uint256 len,
bytes1 needle
) internal pure returns (uint256) {
for (uint256 idx = off; idx < off + len; idx++) {
if (self[idx] == needle) {
return idx;
}
}
return type(uint256).max;
}
}
文件 4 的 22:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 5 的 22:Controllable.sol
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/access/Ownable.sol";
contract Controllable is Ownable {
mapping(address => bool) public controllers;
event ControllerChanged(address indexed controller, bool enabled);
modifier onlyController() {
require(
controllers[msg.sender],
"Controllable: Caller is not a controller"
);
_;
}
function setController(address controller, bool enabled) public onlyOwner {
controllers[controller] = enabled;
emit ControllerChanged(controller, enabled);
}
}
文件 6 的 22:DNSClaimChecker.sol
pragma solidity ^0.8.4;
import "../dnssec-oracle/DNSSEC.sol";
import "../dnssec-oracle/BytesUtils.sol";
import "../dnssec-oracle/RRUtils.sol";
import "../utils/HexUtils.sol";
import "@ensdomains/buffer/contracts/Buffer.sol";
library DNSClaimChecker {
using BytesUtils for bytes;
using HexUtils for bytes;
using RRUtils for *;
using Buffer for Buffer.buffer;
uint16 constant CLASS_INET = 1;
uint16 constant TYPE_TXT = 16;
function getOwnerAddress(
bytes memory name,
bytes memory data
) internal pure returns (address, bool) {
Buffer.buffer memory buf;
buf.init(name.length + 5);
buf.append("\x04_ens");
buf.append(name);
for (
RRUtils.RRIterator memory iter = data.iterateRRs(0);
!iter.done();
iter.next()
) {
if (iter.name().compareNames(buf.buf) != 0) continue;
bool found;
address addr;
(addr, found) = parseRR(data, iter.rdataOffset, iter.nextOffset);
if (found) {
return (addr, true);
}
}
return (address(0x0), false);
}
function parseRR(
bytes memory rdata,
uint256 idx,
uint256 endIdx
) internal pure returns (address, bool) {
while (idx < endIdx) {
uint256 len = rdata.readUint8(idx);
idx += 1;
bool found;
address addr;
(addr, found) = parseString(rdata, idx, len);
if (found) return (addr, true);
idx += len;
}
return (address(0x0), false);
}
function parseString(
bytes memory str,
uint256 idx,
uint256 len
) internal pure returns (address, bool) {
if (str.readUint32(idx) != 0x613d3078) return (address(0x0), false);
return str.hexToAddress(idx + 4, idx + len);
}
}
文件 7 的 22:DNSRegistrar.sol
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@ensdomains/buffer/contracts/Buffer.sol";
import "../dnssec-oracle/BytesUtils.sol";
import "../dnssec-oracle/DNSSEC.sol";
import "../dnssec-oracle/RRUtils.sol";
import "../registry/ENSRegistry.sol";
import "../root/Root.sol";
import "../resolvers/profiles/AddrResolver.sol";
import "./DNSClaimChecker.sol";
import "./PublicSuffixList.sol";
import "./IDNSRegistrar.sol";
contract DNSRegistrar is IDNSRegistrar, IERC165 {
using BytesUtils for bytes;
using Buffer for Buffer.buffer;
using RRUtils for *;
ENS public immutable ens;
DNSSEC public immutable oracle;
PublicSuffixList public suffixes;
address public immutable previousRegistrar;
address public immutable resolver;
mapping(bytes32 => uint32) public inceptions;
error NoOwnerRecordFound();
error PermissionDenied(address caller, address owner);
error PreconditionNotMet();
error StaleProof();
error InvalidPublicSuffix(bytes name);
struct OwnerRecord {
bytes name;
address owner;
address resolver;
uint64 ttl;
}
event Claim(
bytes32 indexed node,
address indexed owner,
bytes dnsname,
uint32 inception
);
event NewPublicSuffixList(address suffixes);
constructor(
address _previousRegistrar,
address _resolver,
DNSSEC _dnssec,
PublicSuffixList _suffixes,
ENS _ens
) {
previousRegistrar = _previousRegistrar;
resolver = _resolver;
oracle = _dnssec;
suffixes = _suffixes;
emit NewPublicSuffixList(address(suffixes));
ens = _ens;
}
modifier onlyOwner() {
Root root = Root(ens.owner(bytes32(0)));
address owner = root.owner();
require(msg.sender == owner);
_;
}
function setPublicSuffixList(PublicSuffixList _suffixes) public onlyOwner {
suffixes = _suffixes;
emit NewPublicSuffixList(address(suffixes));
}
function proveAndClaim(
bytes memory name,
DNSSEC.RRSetWithSignature[] memory input
) public override {
(bytes32 rootNode, bytes32 labelHash, address addr) = _claim(
name,
input
);
ens.setSubnodeOwner(rootNode, labelHash, addr);
}
function proveAndClaimWithResolver(
bytes memory name,
DNSSEC.RRSetWithSignature[] memory input,
address resolver,
address addr
) public override {
(bytes32 rootNode, bytes32 labelHash, address owner) = _claim(
name,
input
);
if (msg.sender != owner) {
revert PermissionDenied(msg.sender, owner);
}
ens.setSubnodeRecord(rootNode, labelHash, owner, resolver, 0);
if (addr != address(0)) {
if (resolver == address(0)) {
revert PreconditionNotMet();
}
bytes32 node = keccak256(abi.encodePacked(rootNode, labelHash));
AddrResolver(resolver).setAddr(node, addr);
}
}
function supportsInterface(
bytes4 interfaceID
) external pure override returns (bool) {
return
interfaceID == type(IERC165).interfaceId ||
interfaceID == type(IDNSRegistrar).interfaceId;
}
function _claim(
bytes memory name,
DNSSEC.RRSetWithSignature[] memory input
) internal returns (bytes32 parentNode, bytes32 labelHash, address addr) {
(bytes memory data, uint32 inception) = oracle.verifyRRSet(input);
uint256 labelLen = name.readUint8(0);
labelHash = name.keccak(1, labelLen);
bytes memory parentName = name.substring(
labelLen + 1,
name.length - labelLen - 1
);
parentNode = enableNode(parentName);
bytes32 node = keccak256(abi.encodePacked(parentNode, labelHash));
if (!RRUtils.serialNumberGte(inception, inceptions[node])) {
revert StaleProof();
}
inceptions[node] = inception;
bool found;
(addr, found) = DNSClaimChecker.getOwnerAddress(name, data);
if (!found) {
revert NoOwnerRecordFound();
}
emit Claim(node, addr, name, inception);
}
function enableNode(bytes memory domain) public returns (bytes32 node) {
if (!suffixes.isPublicSuffix(domain)) {
revert InvalidPublicSuffix(domain);
}
return _enableNode(domain, 0);
}
function _enableNode(
bytes memory domain,
uint256 offset
) internal returns (bytes32 node) {
uint256 len = domain.readUint8(offset);
if (len == 0) {
return bytes32(0);
}
bytes32 parentNode = _enableNode(domain, offset + len + 1);
bytes32 label = domain.keccak(offset + 1, len);
node = keccak256(abi.encodePacked(parentNode, label));
address owner = ens.owner(node);
if (owner == address(0) || owner == previousRegistrar) {
if (parentNode == bytes32(0)) {
Root root = Root(ens.owner(bytes32(0)));
root.setSubnodeOwner(label, address(this));
ens.setResolver(node, resolver);
} else {
ens.setSubnodeRecord(
parentNode,
label,
address(this),
resolver,
0
);
}
} else if (owner != address(this)) {
revert PreconditionNotMet();
}
return node;
}
}
文件 8 的 22:DNSSEC.sol
pragma solidity ^0.8.4;
pragma experimental ABIEncoderV2;
abstract contract DNSSEC {
bytes public anchors;
struct RRSetWithSignature {
bytes rrset;
bytes sig;
}
event AlgorithmUpdated(uint8 id, address addr);
event DigestUpdated(uint8 id, address addr);
function verifyRRSet(
RRSetWithSignature[] memory input
) external view virtual returns (bytes memory rrs, uint32 inception);
function verifyRRSet(
RRSetWithSignature[] memory input,
uint256 now
) public view virtual returns (bytes memory rrs, uint32 inception);
}
文件 9 的 22:ENS.sol
pragma solidity >=0.8.4;
interface ENS {
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
event Transfer(bytes32 indexed node, address owner);
event NewResolver(bytes32 indexed node, address resolver);
event NewTTL(bytes32 indexed node, uint64 ttl);
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
function setRecord(
bytes32 node,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeRecord(
bytes32 node,
bytes32 label,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) external returns (bytes32);
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function setApprovalForAll(address operator, bool approved) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
function recordExists(bytes32 node) external view returns (bool);
function isApprovedForAll(
address owner,
address operator
) external view returns (bool);
}
文件 10 的 22:ENSRegistry.sol
pragma solidity >=0.8.4;
import "./ENS.sol";
contract ENSRegistry is ENS {
struct Record {
address owner;
address resolver;
uint64 ttl;
}
mapping(bytes32 => Record) records;
mapping(address => mapping(address => bool)) operators;
modifier authorised(bytes32 node) {
address owner = records[node].owner;
require(owner == msg.sender || operators[owner][msg.sender]);
_;
}
constructor() public {
records[0x0].owner = msg.sender;
}
function setRecord(
bytes32 node,
address owner,
address resolver,
uint64 ttl
) external virtual override {
setOwner(node, owner);
_setResolverAndTTL(node, resolver, ttl);
}
function setSubnodeRecord(
bytes32 node,
bytes32 label,
address owner,
address resolver,
uint64 ttl
) external virtual override {
bytes32 subnode = setSubnodeOwner(node, label, owner);
_setResolverAndTTL(subnode, resolver, ttl);
}
function setOwner(
bytes32 node,
address owner
) public virtual override authorised(node) {
_setOwner(node, owner);
emit Transfer(node, owner);
}
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) public virtual override authorised(node) returns (bytes32) {
bytes32 subnode = keccak256(abi.encodePacked(node, label));
_setOwner(subnode, owner);
emit NewOwner(node, label, owner);
return subnode;
}
function setResolver(
bytes32 node,
address resolver
) public virtual override authorised(node) {
emit NewResolver(node, resolver);
records[node].resolver = resolver;
}
function setTTL(
bytes32 node,
uint64 ttl
) public virtual override authorised(node) {
emit NewTTL(node, ttl);
records[node].ttl = ttl;
}
function setApprovalForAll(
address operator,
bool approved
) external virtual override {
operators[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function owner(
bytes32 node
) public view virtual override returns (address) {
address addr = records[node].owner;
if (addr == address(this)) {
return address(0x0);
}
return addr;
}
function resolver(
bytes32 node
) public view virtual override returns (address) {
return records[node].resolver;
}
function ttl(bytes32 node) public view virtual override returns (uint64) {
return records[node].ttl;
}
function recordExists(
bytes32 node
) public view virtual override returns (bool) {
return records[node].owner != address(0x0);
}
function isApprovedForAll(
address owner,
address operator
) external view virtual override returns (bool) {
return operators[owner][operator];
}
function _setOwner(bytes32 node, address owner) internal virtual {
records[node].owner = owner;
}
function _setResolverAndTTL(
bytes32 node,
address resolver,
uint64 ttl
) internal {
if (resolver != records[node].resolver) {
records[node].resolver = resolver;
emit NewResolver(node, resolver);
}
if (ttl != records[node].ttl) {
records[node].ttl = ttl;
emit NewTTL(node, ttl);
}
}
}
文件 11 的 22:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 12 的 22:HexUtils.sol
pragma solidity ^0.8.4;
library HexUtils {
function hexStringToBytes32(
bytes memory str,
uint256 idx,
uint256 lastIdx
) internal pure returns (bytes32 r, bool valid) {
uint256 hexLength = lastIdx - idx;
if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {
revert("Invalid string length");
}
valid = true;
assembly {
if gt(lastIdx, mload(str)) {
revert(0, 0)
}
function getHex(c) -> ascii {
if and(gt(c, 47), lt(c, 58)) {
ascii := sub(c, 48)
leave
}
if and(gt(c, 64), lt(c, 71)) {
ascii := add(sub(c, 65), 10)
leave
}
if and(gt(c, 96), lt(c, 103)) {
ascii := add(sub(c, 97), 10)
leave
}
ascii := 0xff
}
let ptr := add(str, 32)
for {
let i := idx
} lt(i, lastIdx) {
i := add(i, 2)
} {
let byte1 := getHex(byte(0, mload(add(ptr, i))))
let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))
if or(eq(byte1, 0xff), eq(byte2, 0xff)) {
valid := false
break
}
let combined := or(shl(4, byte1), byte2)
r := or(shl(8, r), combined)
}
}
}
function hexToAddress(
bytes memory str,
uint256 idx,
uint256 lastIdx
) internal pure returns (address, bool) {
if (lastIdx - idx < 40) return (address(0x0), false);
(bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);
return (address(uint160(uint256(r))), valid);
}
}
文件 13 的 22:IAddrResolver.sol
pragma solidity >=0.8.4;
interface IAddrResolver {
event AddrChanged(bytes32 indexed node, address a);
function addr(bytes32 node) external view returns (address payable);
}
文件 14 的 22:IAddressResolver.sol
pragma solidity >=0.8.4;
interface IAddressResolver {
event AddressChanged(
bytes32 indexed node,
uint256 coinType,
bytes newAddress
);
function addr(
bytes32 node,
uint256 coinType
) external view returns (bytes memory);
}
文件 15 的 22:IDNSRegistrar.sol
pragma solidity ^0.8.4;
import "../dnssec-oracle/DNSSEC.sol";
interface IDNSRegistrar {
function proveAndClaim(
bytes memory name,
DNSSEC.RRSetWithSignature[] memory input
) external;
function proveAndClaimWithResolver(
bytes memory name,
DNSSEC.RRSetWithSignature[] memory input,
address resolver,
address addr
) external;
}
文件 16 的 22:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 17 的 22:IVersionableResolver.sol
pragma solidity >=0.8.4;
interface IVersionableResolver {
event VersionChanged(bytes32 indexed node, uint64 newVersion);
function recordVersions(bytes32 node) external view returns (uint64);
}
文件 18 的 22:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 19 的 22:PublicSuffixList.sol
pragma solidity ^0.8.4;
interface PublicSuffixList {
function isPublicSuffix(bytes calldata name) external view returns (bool);
}
文件 20 的 22:RRUtils.sol
pragma solidity ^0.8.4;
import "./BytesUtils.sol";
import "@ensdomains/buffer/contracts/Buffer.sol";
library RRUtils {
using BytesUtils for *;
using Buffer for *;
function nameLength(
bytes memory self,
uint256 offset
) internal pure returns (uint256) {
uint256 idx = offset;
while (true) {
assert(idx < self.length);
uint256 labelLen = self.readUint8(idx);
idx += labelLen + 1;
if (labelLen == 0) {
break;
}
}
return idx - offset;
}
function readName(
bytes memory self,
uint256 offset
) internal pure returns (bytes memory ret) {
uint256 len = nameLength(self, offset);
return self.substring(offset, len);
}
function labelCount(
bytes memory self,
uint256 offset
) internal pure returns (uint256) {
uint256 count = 0;
while (true) {
assert(offset < self.length);
uint256 labelLen = self.readUint8(offset);
offset += labelLen + 1;
if (labelLen == 0) {
break;
}
count += 1;
}
return count;
}
uint256 constant RRSIG_TYPE = 0;
uint256 constant RRSIG_ALGORITHM = 2;
uint256 constant RRSIG_LABELS = 3;
uint256 constant RRSIG_TTL = 4;
uint256 constant RRSIG_EXPIRATION = 8;
uint256 constant RRSIG_INCEPTION = 12;
uint256 constant RRSIG_KEY_TAG = 16;
uint256 constant RRSIG_SIGNER_NAME = 18;
struct SignedSet {
uint16 typeCovered;
uint8 algorithm;
uint8 labels;
uint32 ttl;
uint32 expiration;
uint32 inception;
uint16 keytag;
bytes signerName;
bytes data;
bytes name;
}
function readSignedSet(
bytes memory data
) internal pure returns (SignedSet memory self) {
self.typeCovered = data.readUint16(RRSIG_TYPE);
self.algorithm = data.readUint8(RRSIG_ALGORITHM);
self.labels = data.readUint8(RRSIG_LABELS);
self.ttl = data.readUint32(RRSIG_TTL);
self.expiration = data.readUint32(RRSIG_EXPIRATION);
self.inception = data.readUint32(RRSIG_INCEPTION);
self.keytag = data.readUint16(RRSIG_KEY_TAG);
self.signerName = readName(data, RRSIG_SIGNER_NAME);
self.data = data.substring(
RRSIG_SIGNER_NAME + self.signerName.length,
data.length - RRSIG_SIGNER_NAME - self.signerName.length
);
}
function rrs(
SignedSet memory rrset
) internal pure returns (RRIterator memory) {
return iterateRRs(rrset.data, 0);
}
struct RRIterator {
bytes data;
uint256 offset;
uint16 dnstype;
uint16 class;
uint32 ttl;
uint256 rdataOffset;
uint256 nextOffset;
}
function iterateRRs(
bytes memory self,
uint256 offset
) internal pure returns (RRIterator memory ret) {
ret.data = self;
ret.nextOffset = offset;
next(ret);
}
function done(RRIterator memory iter) internal pure returns (bool) {
return iter.offset >= iter.data.length;
}
function next(RRIterator memory iter) internal pure {
iter.offset = iter.nextOffset;
if (iter.offset >= iter.data.length) {
return;
}
uint256 off = iter.offset + nameLength(iter.data, iter.offset);
iter.dnstype = iter.data.readUint16(off);
off += 2;
iter.class = iter.data.readUint16(off);
off += 2;
iter.ttl = iter.data.readUint32(off);
off += 4;
uint256 rdataLength = iter.data.readUint16(off);
off += 2;
iter.rdataOffset = off;
iter.nextOffset = off + rdataLength;
}
function name(RRIterator memory iter) internal pure returns (bytes memory) {
return
iter.data.substring(
iter.offset,
nameLength(iter.data, iter.offset)
);
}
function rdata(
RRIterator memory iter
) internal pure returns (bytes memory) {
return
iter.data.substring(
iter.rdataOffset,
iter.nextOffset - iter.rdataOffset
);
}
uint256 constant DNSKEY_FLAGS = 0;
uint256 constant DNSKEY_PROTOCOL = 2;
uint256 constant DNSKEY_ALGORITHM = 3;
uint256 constant DNSKEY_PUBKEY = 4;
struct DNSKEY {
uint16 flags;
uint8 protocol;
uint8 algorithm;
bytes publicKey;
}
function readDNSKEY(
bytes memory data,
uint256 offset,
uint256 length
) internal pure returns (DNSKEY memory self) {
self.flags = data.readUint16(offset + DNSKEY_FLAGS);
self.protocol = data.readUint8(offset + DNSKEY_PROTOCOL);
self.algorithm = data.readUint8(offset + DNSKEY_ALGORITHM);
self.publicKey = data.substring(
offset + DNSKEY_PUBKEY,
length - DNSKEY_PUBKEY
);
}
uint256 constant DS_KEY_TAG = 0;
uint256 constant DS_ALGORITHM = 2;
uint256 constant DS_DIGEST_TYPE = 3;
uint256 constant DS_DIGEST = 4;
struct DS {
uint16 keytag;
uint8 algorithm;
uint8 digestType;
bytes digest;
}
function readDS(
bytes memory data,
uint256 offset,
uint256 length
) internal pure returns (DS memory self) {
self.keytag = data.readUint16(offset + DS_KEY_TAG);
self.algorithm = data.readUint8(offset + DS_ALGORITHM);
self.digestType = data.readUint8(offset + DS_DIGEST_TYPE);
self.digest = data.substring(offset + DS_DIGEST, length - DS_DIGEST);
}
function isSubdomainOf(
bytes memory self,
bytes memory other
) internal pure returns (bool) {
uint256 off = 0;
uint256 counts = labelCount(self, 0);
uint256 othercounts = labelCount(other, 0);
while (counts > othercounts) {
off = progress(self, off);
counts--;
}
return self.equals(off, other, 0);
}
function compareNames(
bytes memory self,
bytes memory other
) internal pure returns (int256) {
if (self.equals(other)) {
return 0;
}
uint256 off;
uint256 otheroff;
uint256 prevoff;
uint256 otherprevoff;
uint256 counts = labelCount(self, 0);
uint256 othercounts = labelCount(other, 0);
while (counts > othercounts) {
prevoff = off;
off = progress(self, off);
counts--;
}
while (othercounts > counts) {
otherprevoff = otheroff;
otheroff = progress(other, otheroff);
othercounts--;
}
while (counts > 0 && !self.equals(off, other, otheroff)) {
prevoff = off;
off = progress(self, off);
otherprevoff = otheroff;
otheroff = progress(other, otheroff);
counts -= 1;
}
if (off == 0) {
return -1;
}
if (otheroff == 0) {
return 1;
}
return
self.compare(
prevoff + 1,
self.readUint8(prevoff),
other,
otherprevoff + 1,
other.readUint8(otherprevoff)
);
}
function serialNumberGte(
uint32 i1,
uint32 i2
) internal pure returns (bool) {
unchecked {
return int32(i1) - int32(i2) >= 0;
}
}
function progress(
bytes memory body,
uint256 off
) internal pure returns (uint256) {
return off + 1 + body.readUint8(off);
}
function computeKeytag(bytes memory data) internal pure returns (uint16) {
unchecked {
require(data.length <= 8192, "Long keys not permitted");
uint256 ac1;
uint256 ac2;
for (uint256 i = 0; i < data.length + 31; i += 32) {
uint256 word;
assembly {
word := mload(add(add(data, 32), i))
}
if (i + 32 > data.length) {
uint256 unused = 256 - (data.length - i) * 8;
word = (word >> unused) << unused;
}
ac1 +=
(word &
0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >>
8;
ac2 += (word &
0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF);
}
ac1 =
(ac1 &
0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) +
((ac1 &
0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >>
16);
ac2 =
(ac2 &
0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) +
((ac2 &
0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >>
16);
ac1 = (ac1 << 8) + ac2;
ac1 =
(ac1 &
0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) +
((ac1 &
0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >>
32);
ac1 =
(ac1 &
0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) +
((ac1 &
0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >>
64);
ac1 =
(ac1 &
0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) +
(ac1 >> 128);
ac1 += (ac1 >> 16) & 0xFFFF;
return uint16(ac1);
}
}
}
文件 21 的 22:ResolverBase.sol
pragma solidity >=0.8.4;
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "./profiles/IVersionableResolver.sol";
abstract contract ResolverBase is ERC165, IVersionableResolver {
mapping(bytes32 => uint64) public recordVersions;
function isAuthorised(bytes32 node) internal view virtual returns (bool);
modifier authorised(bytes32 node) {
require(isAuthorised(node));
_;
}
function clearRecords(bytes32 node) public virtual authorised(node) {
recordVersions[node]++;
emit VersionChanged(node, recordVersions[node]);
}
function supportsInterface(
bytes4 interfaceID
) public view virtual override returns (bool) {
return
interfaceID == type(IVersionableResolver).interfaceId ||
super.supportsInterface(interfaceID);
}
}
文件 22 的 22:Root.sol
pragma solidity ^0.8.4;
import "../registry/ENS.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./Controllable.sol";
contract Root is Ownable, Controllable {
bytes32 private constant ROOT_NODE = bytes32(0);
bytes4 private constant INTERFACE_META_ID =
bytes4(keccak256("supportsInterface(bytes4)"));
event TLDLocked(bytes32 indexed label);
ENS public ens;
mapping(bytes32 => bool) public locked;
constructor(ENS _ens) public {
ens = _ens;
}
function setSubnodeOwner(
bytes32 label,
address owner
) external onlyController {
require(!locked[label]);
ens.setSubnodeOwner(ROOT_NODE, label, owner);
}
function setResolver(address resolver) external onlyOwner {
ens.setResolver(ROOT_NODE, resolver);
}
function lock(bytes32 label) external onlyOwner {
emit TLDLocked(label);
locked[label] = true;
}
function supportsInterface(
bytes4 interfaceID
) external pure returns (bool) {
return interfaceID == INTERFACE_META_ID;
}
}
{
"compilationTarget": {
"contracts/dnsregistrar/DNSRegistrar.sol": "DNSRegistrar"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 1200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_previousRegistrar","type":"address"},{"internalType":"address","name":"_resolver","type":"address"},{"internalType":"contract DNSSEC","name":"_dnssec","type":"address"},{"internalType":"contract PublicSuffixList","name":"_suffixes","type":"address"},{"internalType":"contract ENS","name":"_ens","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"}],"name":"InvalidPublicSuffix","type":"error"},{"inputs":[],"name":"NoOwnerRecordFound","type":"error"},{"inputs":[{"internalType":"uint256","name":"offset","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"OffsetOutOfBoundsError","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"PermissionDenied","type":"error"},{"inputs":[],"name":"PreconditionNotMet","type":"error"},{"inputs":[],"name":"StaleProof","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bytes","name":"dnsname","type":"bytes"},{"indexed":false,"internalType":"uint32","name":"inception","type":"uint32"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"suffixes","type":"address"}],"name":"NewPublicSuffixList","type":"event"},{"inputs":[{"internalType":"bytes","name":"domain","type":"bytes"}],"name":"enableNode","outputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ens","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"inceptions","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract DNSSEC","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previousRegistrar","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"components":[{"internalType":"bytes","name":"rrset","type":"bytes"},{"internalType":"bytes","name":"sig","type":"bytes"}],"internalType":"struct DNSSEC.RRSetWithSignature[]","name":"input","type":"tuple[]"}],"name":"proveAndClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"components":[{"internalType":"bytes","name":"rrset","type":"bytes"},{"internalType":"bytes","name":"sig","type":"bytes"}],"internalType":"struct DNSSEC.RRSetWithSignature[]","name":"input","type":"tuple[]"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"address","name":"addr","type":"address"}],"name":"proveAndClaimWithResolver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract PublicSuffixList","name":"_suffixes","type":"address"}],"name":"setPublicSuffixList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"suffixes","outputs":[{"internalType":"contract PublicSuffixList","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}]