Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,440 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Prove And Claim | 20408920 | 161 days ago | IN | 0 ETH | 0.00015604 | ||||
Prove And Claim ... | 20100691 | 204 days ago | IN | 0 ETH | 0.0001889 | ||||
Prove And Claim ... | 19735846 | 255 days ago | IN | 0 ETH | 0.00062127 | ||||
Prove And Claim ... | 19110286 | 342 days ago | IN | 0 ETH | 0.01428441 | ||||
Prove And Claim ... | 19093081 | 345 days ago | IN | 0 ETH | 0.01014858 | ||||
Prove And Claim ... | 19071872 | 348 days ago | IN | 0 ETH | 0.04930228 | ||||
Prove And Claim ... | 19071777 | 348 days ago | IN | 0 ETH | 0.05469517 | ||||
Prove And Claim ... | 19069445 | 348 days ago | IN | 0 ETH | 0.01336737 | ||||
Prove And Claim ... | 19065283 | 349 days ago | IN | 0 ETH | 0.05875176 | ||||
Prove And Claim ... | 19062441 | 349 days ago | IN | 0 ETH | 0.05958477 | ||||
Prove And Claim ... | 19052316 | 351 days ago | IN | 0 ETH | 0.00159543 | ||||
Prove And Claim ... | 19052297 | 351 days ago | IN | 0 ETH | 0.05300303 | ||||
Prove And Claim | 19040859 | 352 days ago | IN | 0 ETH | 0.01763473 | ||||
Prove And Claim ... | 18996884 | 358 days ago | IN | 0 ETH | 0.00128466 | ||||
Prove And Claim ... | 18988255 | 359 days ago | IN | 0 ETH | 0.00979525 | ||||
Prove And Claim ... | 18963757 | 363 days ago | IN | 0 ETH | 0.01928365 | ||||
Prove And Claim ... | 18945506 | 365 days ago | IN | 0 ETH | 0.03838473 | ||||
Prove And Claim ... | 18931835 | 367 days ago | IN | 0 ETH | 0.0945959 | ||||
Prove And Claim ... | 18919974 | 369 days ago | IN | 0 ETH | 0.09490433 | ||||
Prove And Claim ... | 18909128 | 371 days ago | IN | 0 ETH | 0.04384593 | ||||
Prove And Claim ... | 18905519 | 371 days ago | IN | 0 ETH | 0.01889442 | ||||
Prove And Claim | 18893241 | 373 days ago | IN | 0 ETH | 0.05283019 | ||||
Prove And Claim ... | 18880395 | 375 days ago | IN | 0 ETH | 0.0909986 | ||||
Prove And Claim ... | 18876641 | 375 days ago | IN | 0 ETH | 0.0922969 | ||||
Prove And Claim ... | 18876007 | 375 days ago | IN | 0 ETH | 0.10951873 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
DNSRegistrar
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.8.4; pragma experimental ABIEncoderV2; import "../dnssec-oracle/BytesUtils.sol"; import "../dnssec-oracle/DNSSEC.sol"; import "../registry/ENSRegistry.sol"; import "../root/Root.sol"; import "./DNSClaimChecker.sol"; import "./PublicSuffixList.sol"; import "../resolvers/profiles/AddrResolver.sol"; interface IDNSRegistrar { function claim(bytes memory name, bytes memory proof) external; function proveAndClaim(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof) external; function proveAndClaimWithResolver(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof, address resolver, address addr) external; } /** * @dev An ENS registrar that allows the owner of a DNS name to claim the * corresponding name in ENS. */ contract DNSRegistrar is IDNSRegistrar { using BytesUtils for bytes; DNSSEC public oracle; ENS public ens; PublicSuffixList public suffixes; bytes4 constant private INTERFACE_META_ID = bytes4(keccak256("supportsInterface(bytes4)")); event Claim(bytes32 indexed node, address indexed owner, bytes dnsname); event NewOracle(address oracle); event NewPublicSuffixList(address suffixes); constructor(DNSSEC _dnssec, PublicSuffixList _suffixes, ENS _ens) { oracle = _dnssec; emit NewOracle(address(oracle)); suffixes = _suffixes; emit NewPublicSuffixList(address(suffixes)); ens = _ens; } /** * @dev This contract's owner-only functions can be invoked by the owner of the ENS root. */ modifier onlyOwner { Root root = Root(ens.owner(bytes32(0))); address owner = root.owner(); require(msg.sender == owner); _; } function setOracle(DNSSEC _dnssec) public onlyOwner { oracle = _dnssec; emit NewOracle(address(oracle)); } function setPublicSuffixList(PublicSuffixList _suffixes) public onlyOwner { suffixes = _suffixes; emit NewPublicSuffixList(address(suffixes)); } /** * @dev Claims a name by proving ownership of its DNS equivalent. * @param name The name to claim, in DNS wire format. * @param proof A DNS RRSet proving ownership of the name. Must be verified * in the DNSSEC oracle before calling. This RRSET must contain a TXT * record for '_ens.' + name, with the value 'a=0x...'. Ownership of * the name will be transferred to the address specified in the TXT * record. */ function claim(bytes memory name, bytes memory proof) public override { (bytes32 rootNode, bytes32 labelHash, address addr) = _claim(name, proof); ens.setSubnodeOwner(rootNode, labelHash, addr); } /** * @dev Submits proofs to the DNSSEC oracle, then claims a name using those proofs. * @param name The name to claim, in DNS wire format. * @param input The data to be passed to the Oracle's `submitProofs` function. The last * proof must be the TXT record required by the registrar. * @param proof The proof record for the first element in input. */ function proveAndClaim(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof) public override { proof = oracle.submitRRSets(input, proof); claim(name, proof); } function proveAndClaimWithResolver(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof, address resolver, address addr) public override { proof = oracle.submitRRSets(input, proof); (bytes32 rootNode, bytes32 labelHash, address owner) = _claim(name, proof); require(msg.sender == owner, "Only owner can call proveAndClaimWithResolver"); if(addr != address(0)) { require(resolver != address(0), "Cannot set addr if resolver is not set"); // Set ourselves as the owner so we can set a record on the resolver ens.setSubnodeRecord(rootNode, labelHash, address(this), resolver, 0); bytes32 node = keccak256(abi.encodePacked(rootNode, labelHash)); // Set the resolver record AddrResolver(resolver).setAddr(node, addr); // Transfer the record to the owner ens.setOwner(node, owner); } else { ens.setSubnodeRecord(rootNode, labelHash, owner, resolver, 0); } } function supportsInterface(bytes4 interfaceID) external pure returns (bool) { return interfaceID == INTERFACE_META_ID || interfaceID == type(IDNSRegistrar).interfaceId; } function _claim(bytes memory name, bytes memory proof) internal returns(bytes32 rootNode, bytes32 labelHash, address addr) { // Get the first label uint labelLen = name.readUint8(0); labelHash = name.keccak(1, labelLen); // Parent name must be in the public suffix list. bytes memory parentName = name.substring(labelLen + 1, name.length - labelLen - 1); require(suffixes.isPublicSuffix(parentName), "Parent name must be a public suffix"); // Make sure the parent name is enabled rootNode = enableNode(parentName, 0); (addr,) = DNSClaimChecker.getOwnerAddress(oracle, name, proof); emit Claim(keccak256(abi.encodePacked(rootNode, labelHash)), addr, name); } function enableNode(bytes memory domain, uint offset) internal returns(bytes32 node) { uint 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); require(owner == address(0) || owner == address(this), "Cannot enable a name owned by someone else"); if(owner != address(this)) { if(parentNode == bytes32(0)) { Root root = Root(ens.owner(bytes32(0))); root.setSubnodeOwner(label, address(this)); } else { ens.setSubnodeOwner(parentNode, label, address(this)); } } return node; } }
pragma solidity ^0.8.4; /** * @dev A library for working with mutable byte buffers in Solidity. * * Byte buffers are mutable and expandable, and provide a variety of primitives * for writing to them. At any time you can fetch a bytes object containing the * current contents of the buffer. The bytes object should not be stored between * operations, as it may change due to resizing of the buffer. */ library Buffer { /** * @dev Represents a mutable buffer. Buffers have a current value (buf) and * a capacity. The capacity may be longer than the current value, in * which case it can be extended without the need to allocate more memory. */ struct buffer { bytes buf; uint capacity; } /** * @dev Initializes a buffer with an initial capacity. * @param buf The buffer to initialize. * @param capacity The number of bytes of space to allocate the buffer. * @return The buffer, for chaining. */ function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) { if (capacity % 32 != 0) { capacity += 32 - (capacity % 32); } // Allocate space for the buffer data buf.capacity = capacity; assembly { let ptr := mload(0x40) mstore(buf, ptr) mstore(ptr, 0) mstore(0x40, add(32, add(ptr, capacity))) } return buf; } /** * @dev Initializes a new buffer from an existing bytes object. * Changes to the buffer may mutate the original value. * @param b The bytes object to initialize the buffer with. * @return A new buffer. */ 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 max(uint a, uint b) private pure returns(uint) { if (a > b) { return a; } return b; } /** * @dev Sets buffer length to 0. * @param buf The buffer to truncate. * @return The original buffer, for chaining.. */ function truncate(buffer memory buf) internal pure returns (buffer memory) { assembly { let bufptr := mload(buf) mstore(bufptr, 0) } return buf; } /** * @dev Writes a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The start offset to write to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) { require(len <= data.length); if (off + len > buf.capacity) { resize(buf, max(buf.capacity, len + off) * 2); } uint dest; uint src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(add(len, off), buflen) { mstore(bufptr, add(len, off)) } src := add(data, 32) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes 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; } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, len); } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, data.length); } /** * @dev Writes a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write the byte at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) { if (off >= buf.capacity) { resize(buf, buf.capacity * 2); } assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Address = buffer address + sizeof(buffer length) + off let dest := add(add(bufptr, off), 32) mstore8(dest, data) // Update buffer length if we extended it if eq(off, buflen) { mstore(bufptr, add(buflen, 1)) } } return buf; } /** * @dev Appends a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) { return writeUint8(buf, buf.buf.length, data); } /** * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (left-aligned). * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } unchecked { uint mask = (256 ** len) - 1; // Right-align data data = data >> (8 * (32 - len)); assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + sizeof(buffer length) + off + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } } return buf; } /** * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) { return write(buf, off, bytes32(data), 20); } /** * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chhaining. */ function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, bytes32(data), 20); } /** * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, 32); } /** * @dev Writes an integer to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (right-aligned). * @return The original buffer, for chaining. */ function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } uint mask = (256 ** len) - 1; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + off + sizeof(buffer length) + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } return buf; } /** * @dev Appends a byte to the end of the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer. */ function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) { return writeInt(buf, buf.buf.length, data, len); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
pragma solidity ^0.8.4; import "../dnssec-oracle/DNSSEC.sol"; import "../dnssec-oracle/BytesUtils.sol"; import "../dnssec-oracle/RRUtils.sol"; import "@ensdomains/buffer/contracts/Buffer.sol"; library DNSClaimChecker { using BytesUtils for bytes; using RRUtils for *; using Buffer for Buffer.buffer; uint16 constant CLASS_INET = 1; uint16 constant TYPE_TXT = 16; function getOwnerAddress(DNSSEC oracle, bytes memory name, bytes memory proof) internal view returns (address, bool) { // Add "_ens." to the front of the name. Buffer.buffer memory buf; buf.init(name.length + 5); buf.append("\x04_ens"); buf.append(name); bytes20 hash; uint32 expiration; // Check the provided TXT record has been validated by the oracle (, expiration, hash) = oracle.rrdata(TYPE_TXT, buf.buf); if (hash == bytes20(0) && proof.length == 0) return (address(0x0), false); require(hash == bytes20(keccak256(proof))); for (RRUtils.RRIterator memory iter = proof.iterateRRs(0); !iter.done(); iter.next()) { require(RRUtils.serialNumberGte(expiration + iter.ttl, uint32(block.timestamp)), "DNS record is stale; refresh or delete it before proceeding."); bool found; address addr; (addr, found) = parseRR(proof, iter.rdataOffset); if (found) { return (addr, true); } } return (address(0x0), false); } function parseRR(bytes memory rdata, uint idx) internal pure returns (address, bool) { while (idx < rdata.length) { uint 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, uint idx, uint len) internal pure returns (address, bool) { // TODO: More robust parsing that handles whitespace and multiple key/value pairs if (str.readUint32(idx) != 0x613d3078) return (address(0x0), false); // 0x613d3078 == 'a=0x' if (len < 44) return (address(0x0), false); return hexToAddress(str, idx + 4); } function hexToAddress(bytes memory str, uint idx) internal pure returns (address, bool) { if (str.length - idx < 40) return (address(0x0), false); uint ret = 0; for (uint i = idx; i < idx + 40; i++) { ret <<= 4; uint x = str.readUint8(i); if (x >= 48 && x < 58) { ret |= x - 48; } else if (x >= 65 && x < 71) { ret |= x - 55; } else if (x >= 97 && x < 103) { ret |= x - 87; } else { return (address(0x0), false); } } return (address(uint160(ret)), true); } }
pragma solidity ^0.8.4; interface PublicSuffixList { function isPublicSuffix(bytes calldata name) external view returns(bool); }
pragma solidity ^0.8.4; library BytesUtils { /* * @dev Returns the keccak-256 hash of a byte range. * @param self The byte string to hash. * @param offset The position to start hashing at. * @param len The number of bytes to hash. * @return The hash of the byte range. */ function keccak(bytes memory self, uint offset, uint len) internal pure returns (bytes32 ret) { require(offset + len <= self.length); assembly { ret := keccak256(add(add(self, 32), offset), len) } } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two bytes are equal. * @param self The first bytes to compare. * @param other The second bytes to compare. * @return The result of the comparison. */ function compare(bytes memory self, bytes memory other) internal pure returns (int) { return compare(self, 0, self.length, other, 0, other.length); } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two bytes are equal. Comparison is done per-rune, * on unicode codepoints. * @param self The first bytes to compare. * @param offset The offset of self. * @param len The length of self. * @param other The second bytes to compare. * @param otheroffset The offset of the other string. * @param otherlen The length of the other string. * @return The result of the comparison. */ function compare(bytes memory self, uint offset, uint len, bytes memory other, uint otheroffset, uint otherlen) internal pure returns (int) { uint shortest = len; if (otherlen < len) shortest = otherlen; uint selfptr; uint otherptr; assembly { selfptr := add(self, add(offset, 32)) otherptr := add(other, add(otheroffset, 32)) } for (uint idx = 0; idx < shortest; idx += 32) { uint a; uint b; assembly { a := mload(selfptr) b := mload(otherptr) } if (a != b) { // Mask out irrelevant bytes and check again uint mask; if (shortest > 32) { mask = type(uint256).max; } else { mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); } int diff = int(a & mask) - int(b & mask); if (diff != 0) return diff; } selfptr += 32; otherptr += 32; } return int(len) - int(otherlen); } /* * @dev Returns true if the two byte ranges are equal. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @param otherOffset The offset into the second byte range. * @param len The number of bytes to compare * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset, uint len) internal pure returns (bool) { return keccak(self, offset, len) == keccak(other, otherOffset, len); } /* * @dev Returns true if the two byte ranges are equal with offsets. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @param otherOffset The offset into the second byte range. * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset) internal pure returns (bool) { return keccak(self, offset, self.length - offset) == keccak(other, otherOffset, other.length - otherOffset); } /* * @dev Compares a range of 'self' to all of 'other' and returns True iff * they are equal. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, uint offset, bytes memory other) internal pure returns (bool) { return self.length >= offset + other.length && equals(self, offset, other, 0, other.length); } /* * @dev Returns true if the two byte ranges are equal. * @param self The first byte range to compare. * @param other The second byte range to compare. * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, bytes memory other) internal pure returns(bool) { return self.length == other.length && equals(self, 0, other, 0, self.length); } /* * @dev Returns the 8-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 8 bits of the string, interpreted as an integer. */ function readUint8(bytes memory self, uint idx) internal pure returns (uint8 ret) { return uint8(self[idx]); } /* * @dev Returns the 16-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 16 bits of the string, interpreted as an integer. */ function readUint16(bytes memory self, uint idx) internal pure returns (uint16 ret) { require(idx + 2 <= self.length); assembly { ret := and(mload(add(add(self, 2), idx)), 0xFFFF) } } /* * @dev Returns the 32-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bits of the string, interpreted as an integer. */ function readUint32(bytes memory self, uint idx) internal pure returns (uint32 ret) { require(idx + 4 <= self.length); assembly { ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF) } } /* * @dev Returns the 32 byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bytes of the string. */ function readBytes32(bytes memory self, uint idx) internal pure returns (bytes32 ret) { require(idx + 32 <= self.length); assembly { ret := mload(add(add(self, 32), idx)) } } /* * @dev Returns the 32 byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bytes of the string. */ function readBytes20(bytes memory self, uint idx) internal pure returns (bytes20 ret) { require(idx + 20 <= self.length); assembly { ret := and(mload(add(add(self, 32), idx)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000) } } /* * @dev Returns the n byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes. * @param len The number of bytes. * @return The specified 32 bytes of the string. */ function readBytesN(bytes memory self, uint idx, uint 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(uint dest, uint src, uint len) private pure { // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes 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)) } } } /* * @dev Copies a substring into a new byte string. * @param self The byte string to copy from. * @param offset The offset to start copying at. * @param len The number of bytes to copy. */ function substring(bytes memory self, uint offset, uint len) internal pure returns(bytes memory) { require(offset + len <= self.length); bytes memory ret = new bytes(len); uint dest; uint src; assembly { dest := add(ret, 32) src := add(add(self, 32), offset) } memcpy(dest, src, len); return ret; } // Maps characters from 0x30 to 0x7A to their base32 values. // 0xFF represents invalid characters in that range. bytes constant base32HexTable = hex'00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'; /** * @dev Decodes unpadded base32 data of up to one word in length. * @param self The data to decode. * @param off Offset into the string to start at. * @param len Number of characters to decode. * @return The decoded data, left aligned. */ function base32HexDecodeWord(bytes memory self, uint off, uint len) internal pure returns(bytes32) { require(len <= 52); uint ret = 0; uint8 decoded; for(uint i = 0; i < len; i++) { bytes1 char = self[off + i]; require(char >= 0x30 && char <= 0x7A); decoded = uint8(base32HexTable[uint(uint8(char)) - 0x30]); require(decoded <= 0x20); if(i == len - 1) { break; } ret = (ret << 5) | decoded; } uint bitlen = len * 5; if(len % 8 == 0) { // Multiple of 8 characters, no padding ret = (ret << 5) | decoded; } else if(len % 8 == 2) { // Two extra characters - 1 byte ret = (ret << 3) | (decoded >> 2); bitlen -= 2; } else if(len % 8 == 4) { // Four extra characters - 2 bytes ret = (ret << 1) | (decoded >> 4); bitlen -= 4; } else if(len % 8 == 5) { // Five extra characters - 3 bytes ret = (ret << 4) | (decoded >> 1); bitlen -= 1; } else if(len % 8 == 7) { // Seven extra characters - 4 bytes ret = (ret << 2) | (decoded >> 3); bitlen -= 3; } else { revert(); } return bytes32(ret << (256 - bitlen)); } }
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); event NSEC3DigestUpdated(uint8 id, address addr); event RRSetUpdated(bytes name, bytes rrset); function submitRRSets(RRSetWithSignature[] memory input, bytes calldata proof) public virtual returns (bytes memory); function submitRRSet(RRSetWithSignature calldata input, bytes calldata proof) public virtual returns (bytes memory); function deleteRRSet(uint16 deleteType, bytes calldata deleteName, RRSetWithSignature calldata nsec, bytes calldata proof) public virtual; function deleteRRSetNSEC3(uint16 deleteType, bytes memory deleteName, RRSetWithSignature memory closestEncloser, RRSetWithSignature memory nextClosest, bytes memory dnskey) public virtual; function rrdata(uint16 dnstype, bytes calldata name) external virtual view returns (uint32, uint32, bytes20); }
pragma solidity ^0.8.4; import "./BytesUtils.sol"; import "@ensdomains/buffer/contracts/Buffer.sol"; /** * @dev RRUtils is a library that provides utilities for parsing DNS resource records. */ library RRUtils { using BytesUtils for *; using Buffer for *; /** * @dev Returns the number of bytes in the DNS name at 'offset' in 'self'. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return The length of the DNS name at 'offset', in bytes. */ function nameLength(bytes memory self, uint offset) internal pure returns(uint) { uint idx = offset; while (true) { assert(idx < self.length); uint labelLen = self.readUint8(idx); idx += labelLen + 1; if (labelLen == 0) { break; } } return idx - offset; } /** * @dev Returns a DNS format name at the specified offset of self. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return ret The name. */ function readName(bytes memory self, uint offset) internal pure returns(bytes memory ret) { uint len = nameLength(self, offset); return self.substring(offset, len); } /** * @dev Returns the number of labels in the DNS name at 'offset' in 'self'. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return The number of labels in the DNS name at 'offset', in bytes. */ function labelCount(bytes memory self, uint offset) internal pure returns(uint) { uint count = 0; while (true) { assert(offset < self.length); uint labelLen = self.readUint8(offset); offset += labelLen + 1; if (labelLen == 0) { break; } count += 1; } return count; } uint constant RRSIG_TYPE = 0; uint constant RRSIG_ALGORITHM = 2; uint constant RRSIG_LABELS = 3; uint constant RRSIG_TTL = 4; uint constant RRSIG_EXPIRATION = 8; uint constant RRSIG_INCEPTION = 12; uint constant RRSIG_KEY_TAG = 16; uint 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); } /** * @dev An iterator over resource records. */ struct RRIterator { bytes data; uint offset; uint16 dnstype; uint16 class; uint32 ttl; uint rdataOffset; uint nextOffset; } /** * @dev Begins iterating over resource records. * @param self The byte string to read from. * @param offset The offset to start reading at. * @return ret An iterator object. */ function iterateRRs(bytes memory self, uint offset) internal pure returns (RRIterator memory ret) { ret.data = self; ret.nextOffset = offset; next(ret); } /** * @dev Returns true iff there are more RRs to iterate. * @param iter The iterator to check. * @return True iff the iterator has finished. */ function done(RRIterator memory iter) internal pure returns(bool) { return iter.offset >= iter.data.length; } /** * @dev Moves the iterator to the next resource record. * @param iter The iterator to advance. */ function next(RRIterator memory iter) internal pure { iter.offset = iter.nextOffset; if (iter.offset >= iter.data.length) { return; } // Skip the name uint off = iter.offset + nameLength(iter.data, iter.offset); // Read type, class, and ttl iter.dnstype = iter.data.readUint16(off); off += 2; iter.class = iter.data.readUint16(off); off += 2; iter.ttl = iter.data.readUint32(off); off += 4; // Read the rdata uint rdataLength = iter.data.readUint16(off); off += 2; iter.rdataOffset = off; iter.nextOffset = off + rdataLength; } /** * @dev Returns the name of the current record. * @param iter The iterator. * @return A new bytes object containing the owner name from the RR. */ function name(RRIterator memory iter) internal pure returns(bytes memory) { return iter.data.substring(iter.offset, nameLength(iter.data, iter.offset)); } /** * @dev Returns the rdata portion of the current record. * @param iter The iterator. * @return A new bytes object containing the RR's RDATA. */ function rdata(RRIterator memory iter) internal pure returns(bytes memory) { return iter.data.substring(iter.rdataOffset, iter.nextOffset - iter.rdataOffset); } uint constant DNSKEY_FLAGS = 0; uint constant DNSKEY_PROTOCOL = 2; uint constant DNSKEY_ALGORITHM = 3; uint constant DNSKEY_PUBKEY = 4; struct DNSKEY { uint16 flags; uint8 protocol; uint8 algorithm; bytes publicKey; } function readDNSKEY(bytes memory data, uint offset, uint 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); } uint constant DS_KEY_TAG = 0; uint constant DS_ALGORITHM = 2; uint constant DS_DIGEST_TYPE = 3; uint constant DS_DIGEST = 4; struct DS { uint16 keytag; uint8 algorithm; uint8 digestType; bytes digest; } function readDS(bytes memory data, uint offset, uint 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); } struct NSEC3 { uint8 hashAlgorithm; uint8 flags; uint16 iterations; bytes salt; bytes32 nextHashedOwnerName; bytes typeBitmap; } uint constant NSEC3_HASH_ALGORITHM = 0; uint constant NSEC3_FLAGS = 1; uint constant NSEC3_ITERATIONS = 2; uint constant NSEC3_SALT_LENGTH = 4; uint constant NSEC3_SALT = 5; function readNSEC3(bytes memory data, uint offset, uint length) internal pure returns(NSEC3 memory self) { uint end = offset + length; self.hashAlgorithm = data.readUint8(offset + NSEC3_HASH_ALGORITHM); self.flags = data.readUint8(offset + NSEC3_FLAGS); self.iterations = data.readUint16(offset + NSEC3_ITERATIONS); uint8 saltLength = data.readUint8(offset + NSEC3_SALT_LENGTH); offset = offset + NSEC3_SALT; self.salt = data.substring(offset, saltLength); offset += saltLength; uint8 nextLength = data.readUint8(offset); require(nextLength <= 32); offset += 1; self.nextHashedOwnerName = data.readBytesN(offset, nextLength); offset += nextLength; self.typeBitmap = data.substring(offset, end - offset); } function checkTypeBitmap(NSEC3 memory self, uint16 rrtype) internal pure returns(bool) { return checkTypeBitmap(self.typeBitmap, 0, rrtype); } /** * @dev Checks if a given RR type exists in a type bitmap. * @param bitmap The byte string to read the type bitmap from. * @param offset The offset to start reading at. * @param rrtype The RR type to check for. * @return True if the type is found in the bitmap, false otherwise. */ function checkTypeBitmap(bytes memory bitmap, uint offset, uint16 rrtype) internal pure returns (bool) { uint8 typeWindow = uint8(rrtype >> 8); uint8 windowByte = uint8((rrtype & 0xff) / 8); uint8 windowBitmask = uint8(uint8(1) << (uint8(7) - uint8(rrtype & 0x7))); for (uint off = offset; off < bitmap.length;) { uint8 window = bitmap.readUint8(off); uint8 len = bitmap.readUint8(off + 1); if (typeWindow < window) { // We've gone past our window; it's not here. return false; } else if (typeWindow == window) { // Check this type bitmap if (len <= windowByte) { // Our type is past the end of the bitmap return false; } return (bitmap.readUint8(off + windowByte + 2) & windowBitmask) != 0; } else { // Skip this type bitmap off += len + 2; } } return false; } function compareNames(bytes memory self, bytes memory other) internal pure returns (int) { if (self.equals(other)) { return 0; } uint off; uint otheroff; uint prevoff; uint otherprevoff; uint counts = labelCount(self, 0); uint othercounts = labelCount(other, 0); // Keep removing labels from the front of the name until both names are equal length while (counts > othercounts) { prevoff = off; off = progress(self, off); counts--; } while (othercounts > counts) { otherprevoff = otheroff; otheroff = progress(other, otheroff); othercounts--; } // Compare the last nonequal labels to each other 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)); } /** * @dev Compares two serial numbers using RFC1982 serial number math. */ function serialNumberGte(uint32 i1, uint32 i2) internal pure returns(bool) { return int32(i1) - int32(i2) >= 0; } function progress(bytes memory body, uint off) internal pure returns(uint) { return off + 1 + body.readUint8(off); } }
pragma solidity >=0.8.4; interface ENS { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); // Logged when an operator is added or removed. event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual; function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual; function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external virtual returns(bytes32); function setResolver(bytes32 node, address resolver) external virtual; function setOwner(bytes32 node, address owner) external virtual; function setTTL(bytes32 node, uint64 ttl) external virtual; function setApprovalForAll(address operator, bool approved) external virtual; function owner(bytes32 node) external virtual view returns (address); function resolver(bytes32 node) external virtual view returns (address); function ttl(bytes32 node) external virtual view returns (uint64); function recordExists(bytes32 node) external virtual view returns (bool); function isApprovedForAll(address owner, address operator) external virtual view returns (bool); }
pragma solidity >=0.8.4; import "./ENS.sol"; /** * The ENS registry contract. */ contract ENSRegistry is ENS { struct Record { address owner; address resolver; uint64 ttl; } mapping (bytes32 => Record) records; mapping (address => mapping(address => bool)) operators; // Permits modifications only by the owner of the specified node. modifier authorised(bytes32 node) { address owner = records[node].owner; require(owner == msg.sender || operators[owner][msg.sender]); _; } /** * @dev Constructs a new ENS registrar. */ constructor() public { records[0x0].owner = msg.sender; } /** * @dev Sets the record for a node. * @param node The node to update. * @param owner The address of the new owner. * @param resolver The address of the resolver. * @param ttl The TTL in seconds. */ function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual override { setOwner(node, owner); _setResolverAndTTL(node, resolver, ttl); } /** * @dev Sets the record for a subnode. * @param node The parent node. * @param label The hash of the label specifying the subnode. * @param owner The address of the new owner. * @param resolver The address of the resolver. * @param ttl The TTL in seconds. */ 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); } /** * @dev Transfers ownership of a node to a new address. May only be called by the current owner of the node. * @param node The node to transfer ownership of. * @param owner The address of the new owner. */ function setOwner(bytes32 node, address owner) public virtual override authorised(node) { _setOwner(node, owner); emit Transfer(node, owner); } /** * @dev Transfers ownership of a subnode keccak256(node, label) to a new address. May only be called by the owner of the parent node. * @param node The parent node. * @param label The hash of the label specifying the subnode. * @param owner The address of the new 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; } /** * @dev Sets the resolver address for the specified node. * @param node The node to update. * @param resolver The address of the resolver. */ function setResolver(bytes32 node, address resolver) public virtual override authorised(node) { emit NewResolver(node, resolver); records[node].resolver = resolver; } /** * @dev Sets the TTL for the specified node. * @param node The node to update. * @param ttl The TTL in seconds. */ function setTTL(bytes32 node, uint64 ttl) public virtual override authorised(node) { emit NewTTL(node, ttl); records[node].ttl = ttl; } /** * @dev Enable or disable approval for a third party ("operator") to manage * all of `msg.sender`'s ENS records. Emits the ApprovalForAll event. * @param operator Address to add to the set of authorized operators. * @param approved True if the operator is approved, false to revoke approval. */ function setApprovalForAll(address operator, bool approved) external virtual override { operators[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } /** * @dev Returns the address that owns the specified node. * @param node The specified node. * @return address of the owner. */ function owner(bytes32 node) public virtual override view returns (address) { address addr = records[node].owner; if (addr == address(this)) { return address(0x0); } return addr; } /** * @dev Returns the address of the resolver for the specified node. * @param node The specified node. * @return address of the resolver. */ function resolver(bytes32 node) public virtual override view returns (address) { return records[node].resolver; } /** * @dev Returns the TTL of a node, and any records associated with it. * @param node The specified node. * @return ttl of the node. */ function ttl(bytes32 node) public virtual override view returns (uint64) { return records[node].ttl; } /** * @dev Returns whether a record has been imported to the registry. * @param node The specified node. * @return Bool if record exists */ function recordExists(bytes32 node) public virtual override view returns (bool) { return records[node].owner != address(0x0); } /** * @dev Query if an address is an authorized operator for another address. * @param owner The address that owns the records. * @param operator The address that acts on behalf of the owner. * @return True if `operator` is an approved operator for `owner`, false otherwise. */ function isApprovedForAll(address owner, address operator) external virtual override view 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); } } }
pragma solidity >=0.8.4; abstract contract ResolverBase { bytes4 private constant INTERFACE_META_ID = 0x01ffc9a7; function supportsInterface(bytes4 interfaceID) virtual public pure returns(bool) { return interfaceID == INTERFACE_META_ID; } function isAuthorised(bytes32 node) internal virtual view returns(bool); modifier authorised(bytes32 node) { require(isAuthorised(node)); _; } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract AddrResolver is ResolverBase { bytes4 constant private ADDR_INTERFACE_ID = 0x3b3b57de; bytes4 constant private ADDRESS_INTERFACE_ID = 0xf1cb7e06; uint constant private COIN_TYPE_ETH = 60; event AddrChanged(bytes32 indexed node, address a); event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress); mapping(bytes32=>mapping(uint=>bytes)) _addresses; /** * Sets the address associated with an ENS node. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param a The address to set. */ function setAddr(bytes32 node, address a) external authorised(node) { setAddr(node, COIN_TYPE_ETH, addressToBytes(a)); } /** * Returns the address associated with an ENS node. * @param node The ENS node to query. * @return The associated address. */ function addr(bytes32 node) public view 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, 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; } function addr(bytes32 node, uint coinType) public view returns(bytes memory) { return _addresses[node][coinType]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == ADDR_INTERFACE_ID || interfaceID == ADDRESS_INTERFACE_ID || 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))) } } }
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); } }
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; } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": false, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"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"},{"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"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"}],"name":"NewOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"suffixes","type":"address"}],"name":"NewPublicSuffixList","type":"event"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ens","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract DNSSEC","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[]"},{"internalType":"bytes","name":"proof","type":"bytes"}],"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":"bytes","name":"proof","type":"bytes"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"address","name":"addr","type":"address"}],"name":"proveAndClaimWithResolver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract DNSSEC","name":"_dnssec","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","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"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003488380380620034888339818101604052810190620000379190620001fb565b826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fb3eacd0e351fafdfefdec84e1cd19679b38dbcd63ea7c2c24da17fd2bc3b3c0e60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051620000c8919062000262565b60405180910390a181600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9176b7f47e4504df5e5516c99d90d82ac7cbd49cc77e7f22ba2ac2f2e3a3eba8600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405162000164919062000262565b60405180910390a180600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050506200033d565b600081519050620001c781620002ef565b92915050565b600081519050620001de8162000309565b92915050565b600081519050620001f58162000323565b92915050565b6000806000606084860312156200021157600080fd5b60006200022186828701620001b6565b93505060206200023486828701620001e4565b92505060406200024786828701620001cd565b9150509250925092565b6200025c816200027f565b82525050565b600060208201905062000279600083018462000251565b92915050565b60006200028c82620002cf565b9050919050565b6000620002a0826200027f565b9050919050565b6000620002b4826200027f565b9050919050565b6000620002c8826200027f565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620002fa8162000293565b81146200030657600080fd5b50565b6200031481620002a7565b81146200032057600080fd5b50565b6200032e81620002bb565b81146200033a57600080fd5b50565b61313b806200034d6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80633f15457f116100665780633f15457f1461011e5780637adbf9731461013c5780637dc0d1d0146101585780638bbedf7514610176578063be27b22c1461019257610093565b806301ffc9a7146100985780631ecfc411146100c8578063224199c2146100e457806330349ebe14610100575b600080fd5b6100b260048036038101906100ad919061211f565b6101ae565b6040516100bf91906126e7565b60405180910390f35b6100e260048036038101906100dd9190612374565b610280565b005b6100fe60048036038101906100f99190612220565b61048b565b005b6101086108cc565b6040516101159190612828565b60405180910390f35b6101266108f2565b604051610133919061280d565b60405180910390f35b6101566004803603810190610151919061234b565b610918565b005b610160610b20565b60405161016d91906127f2565b60405180910390f35b610190600480360381019061018b9190612189565b610b44565b005b6101ac60048036038101906101a791906122df565b610c07565b005b60007f01ffc9a7a5cef8baa21ed3c5c0d7e23accb804b619e9333b597f47a0d84076e27bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061027957507f17d8f49b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be36000801b6040518263ffffffff1660e01b81526004016102e09190612702565b60206040518083038186803b1580156102f857600080fd5b505afa15801561030c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033091906120a4565b905060008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561037a57600080fd5b505afa15801561038e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b291906120a4565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ec57600080fd5b82600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9176b7f47e4504df5e5516c99d90d82ac7cbd49cc77e7f22ba2ac2f2e3a3eba8600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405161047e9190612695565b60405180910390a1505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663435cc16285856040518363ffffffff1660e01b81526004016104e69291906126b0565b600060405180830381600087803b15801561050057600080fd5b505af1158015610514573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061053d9190612148565b9250600080600061054e8887610cd5565b9250925092508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b9906128c3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461082b57600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610666576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065d90612843565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ef2c7f08484308960006040518663ffffffff1660e01b81526004016106ca95949392919061277d565b600060405180830381600087803b1580156106e457600080fd5b505af11580156106f8573d6000803e3d6000fd5b5050505060008383604051602001610711929190612669565b6040516020818303038152906040528051906020012090508573ffffffffffffffffffffffffffffffffffffffff1663d5fa2b0082876040518363ffffffff1660e01b815260040161076492919061271d565b600060405180830381600087803b15801561077e57600080fd5b505af1158015610792573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c382846040518363ffffffff1660e01b81526004016107f392919061271d565b600060405180830381600087803b15801561080d57600080fd5b505af1158015610821573d6000803e3d6000fd5b50505050506108c2565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ef2c7f08484848960006040518663ffffffff1660e01b815260040161088f95949392919061277d565b600060405180830381600087803b1580156108a957600080fd5b505af11580156108bd573d6000803e3d6000fd5b505050505b5050505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be36000801b6040518263ffffffff1660e01b81526004016109789190612702565b60206040518083038186803b15801561099057600080fd5b505afa1580156109a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c891906120a4565b905060008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1257600080fd5b505afa158015610a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4a91906120a4565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a8457600080fd5b826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fb3eacd0e351fafdfefdec84e1cd19679b38dbcd63ea7c2c24da17fd2bc3b3c0e60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051610b139190612695565b60405180910390a1505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663435cc16283836040518363ffffffff1660e01b8152600401610b9f9291906126b0565b600060405180830381600087803b158015610bb957600080fd5b505af1158015610bcd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610bf69190612148565b9050610c028382610c07565b505050565b6000806000610c168585610cd5565b925092509250600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59238484846040518463ffffffff1660e01b8152600401610c7b93929190612746565b602060405180830381600087803b158015610c9557600080fd5b505af1158015610ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccd91906120f6565b505050505050565b600080600080610cef600087610ef090919063ffffffff16565b60ff169050610d0a60018288610f419092919063ffffffff16565b92506000610d47600183610d1e9190612a0c565b6001848a51610d2d9190612b6e565b610d379190612b6e565b89610f6d9092919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f89059e826040518263ffffffff1660e01b8152600401610da491906127d0565b60206040518083038186803b158015610dbc57600080fd5b505afa158015610dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df491906120cd565b610e33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2a90612863565b60405180910390fd5b610e3e816000611028565b9450610e6b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888611443565b50809350508273ffffffffffffffffffffffffffffffffffffffff168585604051602001610e9a929190612669565b604051602081830303815290604052805190602001207fa2e66ce20e6fb2c4f61339c364ad79f15160cf5307230c8bc4d628adbca2ba3989604051610edf91906127d0565b60405180910390a350509250925092565b6000828281518110610f2b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602001015160f81c60f81b60f81c905092915050565b600083518284610f519190612a0c565b1115610f5c57600080fd5b818360208601012090509392505050565b606083518284610f7d9190612a0c565b1115610f8857600080fd5b60008267ffffffffffffffff811115610fca577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015610ffc5781602001600182028036833780820191505090505b509050600080602083019150856020880101905061101b8282876116b4565b8293505050509392505050565b60008061103e8385610ef090919063ffffffff16565b60ff1690506000811415611058576000801b91505061143d565b600061107b856001848761106c9190612a0c565b6110769190612a0c565b611028565b905060006110a060018661108f9190612a0c565b8488610f419092919063ffffffff16565b905081816040516020016110b5929190612669565b6040516020818303038152906040528051906020012093506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3866040518263ffffffff1660e01b815260040161112a9190612702565b60206040518083038186803b15801561114257600080fd5b505afa158015611156573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117a91906120a4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806111e257503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611221576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121890612883565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611438576000801b831415611384576000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be36000801b6040518263ffffffff1660e01b81526004016112bf9190612702565b60206040518083038186803b1580156112d757600080fd5b505afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f91906120a4565b90508073ffffffffffffffffffffffffffffffffffffffff16638cb8ecec84306040518363ffffffff1660e01b815260040161134c92919061271d565b600060405180830381600087803b15801561136657600080fd5b505af115801561137a573d6000803e3d6000fd5b5050505050611437565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59238484306040518463ffffffff1660e01b81526004016113e393929190612746565b602060405180830381600087803b1580156113fd57600080fd5b505af1158015611411573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143591906120f6565b505b5b505050505b92915050565b60008061144e611d86565b61146e6005865161145f9190612a0c565b8261171890919063ffffffff16565b506114b76040518060400160405280600581526020017f045f656e730000000000000000000000000000000000000000000000000000008152508261178290919063ffffffff16565b506114cb858261178290919063ffffffff16565b506000808773ffffffffffffffffffffffffffffffffffffffff1663087991bc601085600001516040518363ffffffff1660e01b815260040161150f9291906128e3565b60606040518083038186803b15801561152757600080fd5b505afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f919061239d565b9091508093508192505050600060601b6bffffffffffffffffffffffff1916826bffffffffffffffffffffffff191614801561159c575060008651145b156115b057600080945094505050506116ac565b85805190602001206bffffffffffffffffffffffff1916826bffffffffffffffffffffffff1916146115e157600080fd5b60006115f76000886117a490919063ffffffff16565b90505b611603816117ce565b6116a05761162081608001518361161a9190612a62565b426117e4565b61165f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611656906128a3565b60405180910390fd5b600080611670898460a00151611800565b8093508192505050811561169057806001975097505050505050506116ac565b505061169b81611886565b6115fa565b50600080945094505050505b935093915050565b5b602081106116f357815183526020836116ce9190612a0c565b92506020826116dd9190612a0c565b91506020816116ec9190612b6e565b90506116b5565b60006001826020036101000a0390508019835116818551168181178652505050505050565b611720611d86565b600060208361172f9190612df3565b1461175b576020826117419190612df3565b602061174d9190612b6e565b826117589190612a0c565b91505b81836020018181525050604051808452600081528281016020016040525082905092915050565b61178a611d86565b61179c838460000151518485516119d0565b905092915050565b6117ac611da0565b828160000181905250818160c00181815250506117c881611886565b92915050565b6000816000015151826020015110159050919050565b60008082846117f39190612af6565b60030b1215905092915050565b6000805b83518310156118775760006118228486610ef090919063ffffffff16565b60ff1690506001846118349190612a0c565b9350600080611844878785611abf565b80935081925050508115611861578060019450945050505061187f565b828661186d9190612a0c565b9550505050611804565b600080915091505b9250929050565b8060c001518160200181815250508060000151518160200151106118a9576119cd565b60006118bd82600001518360200151611b29565b82602001516118cc9190612a0c565b90506118e5818360000151611bcc90919063ffffffff16565b826040019061ffff16908161ffff16815250506002816119059190612a0c565b905061191e818360000151611bcc90919063ffffffff16565b826060019061ffff16908161ffff168152505060028161193e9190612a0c565b9050611957818360000151611bfb90919063ffffffff16565b826080019063ffffffff16908163ffffffff168152505060048161197b9190612a0c565b90506000611996828460000151611bcc90919063ffffffff16565b61ffff1690506002826119a99190612a0c565b9150818360a001818152505080826119c19190612a0c565b8360c001818152505050505b50565b6119d8611d86565b82518211156119e657600080fd5b846020015182856119f79190612a0c565b1115611a2c57611a2b856002611a1c88602001518887611a179190612a0c565b611c2c565b611a269190612a9c565b611c48565b5b600080865180518760208301019350808887011115611a4b5787860182525b60208701925050505b60208410611a925780518252602082611a6d9190612a0c565b9150602081611a7c9190612a0c565b9050602084611a8b9190612b6e565b9350611a54565b60006001856020036101000a03905080198251168184511681811785525050508692505050949350505050565b60008063613d3078611ada8587611bfb90919063ffffffff16565b63ffffffff1614611af15760008091509150611b21565b602c831015611b065760008091509150611b21565b611b1c85600486611b179190612a0c565b611c6c565b915091505b935093915050565b6000808290505b600115611bb75783518110611b6e577f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000611b838286610ef090919063ffffffff16565b60ff169050600181611b959190612a0c565b82611ba09190612a0c565b91506000811415611bb15750611bb7565b50611b30565b8281611bc39190612b6e565b91505092915050565b60008251600283611bdd9190612a0c565b1115611be857600080fd5b61ffff8260028501015116905092915050565b60008251600483611c0c9190612a0c565b1115611c1757600080fd5b63ffffffff8260048501015116905092915050565b600081831115611c3e57829050611c42565b8190505b92915050565b600082600001519050611c5b8383611718565b50611c668382611782565b50505050565b6000806028838551611c7e9190612b6e565b1015611c905760008091509150611d7f565b6000808490505b602885611ca49190612a0c565b811015611d7557600482901b91506000611cc78288610ef090919063ffffffff16565b60ff16905060308110158015611cdd5750603a81105b15611cf857603081611cef9190612b6e565b83179250611d61565b60418110158015611d095750604781105b15611d2457603781611d1b9190612b6e565b83179250611d60565b60618110158015611d355750606781105b15611d5057605781611d479190612b6e565b83179250611d5f565b60008094509450505050611d7f565b5b5b508080611d6d90612da0565b915050611c97565b5080600192509250505b9250929050565b604051806040016040528060608152602001600081525090565b6040518060e001604052806060815260200160008152602001600061ffff168152602001600061ffff168152602001600063ffffffff16815260200160008152602001600081525090565b6000611dfe611df984612938565b612913565b90508083825260208201905082856020860282011115611e1d57600080fd5b60005b85811015611e6757813567ffffffffffffffff811115611e3f57600080fd5b808601611e4c8982612013565b85526020850194506020840193505050600181019050611e20565b5050509392505050565b6000611e84611e7f84612964565b612913565b905082815260208101848484011115611e9c57600080fd5b611ea7848285612d2d565b509392505050565b6000611ec2611ebd84612964565b612913565b905082815260208101848484011115611eda57600080fd5b611ee5848285612d3c565b509392505050565b600081359050611efc8161304d565b92915050565b600081519050611f118161304d565b92915050565b600082601f830112611f2857600080fd5b8135611f38848260208601611deb565b91505092915050565b600081519050611f5081613064565b92915050565b600081519050611f658161307b565b92915050565b600081519050611f7a81613092565b92915050565b600081359050611f8f816130a9565b92915050565b600082601f830112611fa657600080fd5b8135611fb6848260208601611e71565b91505092915050565b600082601f830112611fd057600080fd5b8151611fe0848260208601611eaf565b91505092915050565b600081359050611ff8816130c0565b92915050565b60008135905061200d816130d7565b92915050565b60006040828403121561202557600080fd5b61202f6040612913565b9050600082013567ffffffffffffffff81111561204b57600080fd5b61205784828501611f95565b600083015250602082013567ffffffffffffffff81111561207757600080fd5b61208384828501611f95565b60208301525092915050565b60008151905061209e816130ee565b92915050565b6000602082840312156120b657600080fd5b60006120c484828501611f02565b91505092915050565b6000602082840312156120df57600080fd5b60006120ed84828501611f41565b91505092915050565b60006020828403121561210857600080fd5b600061211684828501611f6b565b91505092915050565b60006020828403121561213157600080fd5b600061213f84828501611f80565b91505092915050565b60006020828403121561215a57600080fd5b600082015167ffffffffffffffff81111561217457600080fd5b61218084828501611fbf565b91505092915050565b60008060006060848603121561219e57600080fd5b600084013567ffffffffffffffff8111156121b857600080fd5b6121c486828701611f95565b935050602084013567ffffffffffffffff8111156121e157600080fd5b6121ed86828701611f17565b925050604084013567ffffffffffffffff81111561220a57600080fd5b61221686828701611f95565b9150509250925092565b600080600080600060a0868803121561223857600080fd5b600086013567ffffffffffffffff81111561225257600080fd5b61225e88828901611f95565b955050602086013567ffffffffffffffff81111561227b57600080fd5b61228788828901611f17565b945050604086013567ffffffffffffffff8111156122a457600080fd5b6122b088828901611f95565b93505060606122c188828901611eed565b92505060806122d288828901611eed565b9150509295509295909350565b600080604083850312156122f257600080fd5b600083013567ffffffffffffffff81111561230c57600080fd5b61231885828601611f95565b925050602083013567ffffffffffffffff81111561233557600080fd5b61234185828601611f95565b9150509250929050565b60006020828403121561235d57600080fd5b600061236b84828501611fe9565b91505092915050565b60006020828403121561238657600080fd5b600061239484828501611ffe565b91505092915050565b6000806000606084860312156123b257600080fd5b60006123c08682870161208f565b93505060206123d18682870161208f565b92505060406123e286828701611f56565b9150509250925092565b60006123f88383612616565b905092915050565b61240981612ba2565b82525050565b600061241a826129a5565b61242481856129c8565b93508360208202850161243685612995565b8060005b85811015612472578484038952815161245385826123ec565b945061245e836129bb565b925060208a0199505060018101905061243a565b50829750879550505050505092915050565b61248d81612bb4565b82525050565b61249c81612bec565b82525050565b6124b36124ae82612bec565b612de9565b82525050565b60006124c4826129b0565b6124ce81856129d9565b93506124de818560208601612d3c565b6124e781612eb1565b840191505092915050565b60006124fd826129b0565b61250781856129ea565b9350612517818560208601612d3c565b61252081612eb1565b840191505092915050565b61253481612caf565b82525050565b61254381612cd3565b82525050565b61255281612cf7565b82525050565b61256181612d1b565b82525050565b60006125746026836129fb565b915061257f82612ec2565b604082019050919050565b60006125976023836129fb565b91506125a282612f11565b604082019050919050565b60006125ba602a836129fb565b91506125c582612f60565b604082019050919050565b60006125dd603c836129fb565b91506125e882612faf565b604082019050919050565b6000612600602d836129fb565b915061260b82612ffe565b604082019050919050565b6000604083016000830151848203600086015261263382826124b9565b9150506020830151848203602086015261264d82826124b9565b9150508091505092915050565b61266381612c53565b82525050565b600061267582856124a2565b60208201915061268582846124a2565b6020820191508190509392505050565b60006020820190506126aa6000830184612400565b92915050565b600060408201905081810360008301526126ca818561240f565b905081810360208301526126de81846124f2565b90509392505050565b60006020820190506126fc6000830184612484565b92915050565b60006020820190506127176000830184612493565b92915050565b60006040820190506127326000830185612493565b61273f6020830184612400565b9392505050565b600060608201905061275b6000830186612493565b6127686020830185612493565b6127756040830184612400565b949350505050565b600060a0820190506127926000830188612493565b61279f6020830187612493565b6127ac6040830186612400565b6127b96060830185612400565b6127c66080830184612558565b9695505050505050565b600060208201905081810360008301526127ea81846124f2565b905092915050565b6000602082019050612807600083018461252b565b92915050565b6000602082019050612822600083018461253a565b92915050565b600060208201905061283d6000830184612549565b92915050565b6000602082019050818103600083015261285c81612567565b9050919050565b6000602082019050818103600083015261287c8161258a565b9050919050565b6000602082019050818103600083015261289c816125ad565b9050919050565b600060208201905081810360008301526128bc816125d0565b9050919050565b600060208201905081810360008301526128dc816125f3565b9050919050565b60006040820190506128f8600083018561265a565b818103602083015261290a81846124f2565b90509392505050565b600061291d61292e565b90506129298282612d6f565b919050565b6000604051905090565b600067ffffffffffffffff82111561295357612952612e82565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561297f5761297e612e82565b5b61298882612eb1565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000612a1782612c81565b9150612a2283612c81565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612a5757612a56612e24565b5b828201905092915050565b6000612a6d82612c8b565b9150612a7883612c8b565b92508263ffffffff03821115612a9157612a90612e24565b5b828201905092915050565b6000612aa782612c81565b9150612ab283612c81565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612aeb57612aea612e24565b5b828202905092915050565b6000612b0182612c46565b9150612b0c83612c46565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000001821260008412151615612b4757612b46612e24565b5b82637fffffff018213600084121615612b6357612b62612e24565b5b828203905092915050565b6000612b7982612c81565b9150612b8483612c81565b925082821015612b9757612b96612e24565b5b828203905092915050565b6000612bad82612c61565b9050919050565b60008115159050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000612c2d82612ba2565b9050919050565b6000612c3f82612ba2565b9050919050565b60008160030b9050919050565b600061ffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600067ffffffffffffffff82169050919050565b6000612cba82612cc1565b9050919050565b6000612ccc82612c61565b9050919050565b6000612cde82612ce5565b9050919050565b6000612cf082612c61565b9050919050565b6000612d0282612d09565b9050919050565b6000612d1482612c61565b9050919050565b6000612d2682612c9b565b9050919050565b82818337600083830152505050565b60005b83811015612d5a578082015181840152602081019050612d3f565b83811115612d69576000848401525b50505050565b612d7882612eb1565b810181811067ffffffffffffffff82111715612d9757612d96612e82565b5b80604052505050565b6000612dab82612c81565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612dde57612ddd612e24565b5b600182019050919050565b6000819050919050565b6000612dfe82612c81565b9150612e0983612c81565b925082612e1957612e18612e53565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f43616e6e6f74207365742061646472206966207265736f6c766572206973206e60008201527f6f74207365740000000000000000000000000000000000000000000000000000602082015250565b7f506172656e74206e616d65206d7573742062652061207075626c69632073756660008201527f6669780000000000000000000000000000000000000000000000000000000000602082015250565b7f43616e6e6f7420656e61626c652061206e616d65206f776e656420627920736f60008201527f6d656f6e6520656c736500000000000000000000000000000000000000000000602082015250565b7f444e53207265636f7264206973207374616c653b2072656672657368206f722060008201527f64656c657465206974206265666f72652070726f63656564696e672e00000000602082015250565b7f4f6e6c79206f776e65722063616e2063616c6c2070726f7665416e64436c616960008201527f6d576974685265736f6c76657200000000000000000000000000000000000000602082015250565b61305681612ba2565b811461306157600080fd5b50565b61306d81612bb4565b811461307857600080fd5b50565b61308481612bc0565b811461308f57600080fd5b50565b61309b81612bec565b81146130a657600080fd5b50565b6130b281612bf6565b81146130bd57600080fd5b50565b6130c981612c22565b81146130d457600080fd5b50565b6130e081612c34565b81146130eb57600080fd5b50565b6130f781612c8b565b811461310257600080fd5b5056fea26469706673582212206ee5cab83a909097227319cce5a4b719af0f19534dc0e6e62503c5f38a59e2e764736f6c6343000804003300000000000000000000000046c6f79952d3046bf673a28132ff2a81f306959c000000000000000000000000d10730069066cda980edfb5e70ef678a38b5265f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100935760003560e01c80633f15457f116100665780633f15457f1461011e5780637adbf9731461013c5780637dc0d1d0146101585780638bbedf7514610176578063be27b22c1461019257610093565b806301ffc9a7146100985780631ecfc411146100c8578063224199c2146100e457806330349ebe14610100575b600080fd5b6100b260048036038101906100ad919061211f565b6101ae565b6040516100bf91906126e7565b60405180910390f35b6100e260048036038101906100dd9190612374565b610280565b005b6100fe60048036038101906100f99190612220565b61048b565b005b6101086108cc565b6040516101159190612828565b60405180910390f35b6101266108f2565b604051610133919061280d565b60405180910390f35b6101566004803603810190610151919061234b565b610918565b005b610160610b20565b60405161016d91906127f2565b60405180910390f35b610190600480360381019061018b9190612189565b610b44565b005b6101ac60048036038101906101a791906122df565b610c07565b005b60007f01ffc9a7a5cef8baa21ed3c5c0d7e23accb804b619e9333b597f47a0d84076e27bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061027957507f17d8f49b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be36000801b6040518263ffffffff1660e01b81526004016102e09190612702565b60206040518083038186803b1580156102f857600080fd5b505afa15801561030c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033091906120a4565b905060008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561037a57600080fd5b505afa15801561038e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b291906120a4565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ec57600080fd5b82600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9176b7f47e4504df5e5516c99d90d82ac7cbd49cc77e7f22ba2ac2f2e3a3eba8600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405161047e9190612695565b60405180910390a1505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663435cc16285856040518363ffffffff1660e01b81526004016104e69291906126b0565b600060405180830381600087803b15801561050057600080fd5b505af1158015610514573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061053d9190612148565b9250600080600061054e8887610cd5565b9250925092508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b9906128c3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461082b57600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610666576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065d90612843565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ef2c7f08484308960006040518663ffffffff1660e01b81526004016106ca95949392919061277d565b600060405180830381600087803b1580156106e457600080fd5b505af11580156106f8573d6000803e3d6000fd5b5050505060008383604051602001610711929190612669565b6040516020818303038152906040528051906020012090508573ffffffffffffffffffffffffffffffffffffffff1663d5fa2b0082876040518363ffffffff1660e01b815260040161076492919061271d565b600060405180830381600087803b15801561077e57600080fd5b505af1158015610792573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c382846040518363ffffffff1660e01b81526004016107f392919061271d565b600060405180830381600087803b15801561080d57600080fd5b505af1158015610821573d6000803e3d6000fd5b50505050506108c2565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ef2c7f08484848960006040518663ffffffff1660e01b815260040161088f95949392919061277d565b600060405180830381600087803b1580156108a957600080fd5b505af11580156108bd573d6000803e3d6000fd5b505050505b5050505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be36000801b6040518263ffffffff1660e01b81526004016109789190612702565b60206040518083038186803b15801561099057600080fd5b505afa1580156109a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c891906120a4565b905060008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1257600080fd5b505afa158015610a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4a91906120a4565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a8457600080fd5b826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fb3eacd0e351fafdfefdec84e1cd19679b38dbcd63ea7c2c24da17fd2bc3b3c0e60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051610b139190612695565b60405180910390a1505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663435cc16283836040518363ffffffff1660e01b8152600401610b9f9291906126b0565b600060405180830381600087803b158015610bb957600080fd5b505af1158015610bcd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610bf69190612148565b9050610c028382610c07565b505050565b6000806000610c168585610cd5565b925092509250600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59238484846040518463ffffffff1660e01b8152600401610c7b93929190612746565b602060405180830381600087803b158015610c9557600080fd5b505af1158015610ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccd91906120f6565b505050505050565b600080600080610cef600087610ef090919063ffffffff16565b60ff169050610d0a60018288610f419092919063ffffffff16565b92506000610d47600183610d1e9190612a0c565b6001848a51610d2d9190612b6e565b610d379190612b6e565b89610f6d9092919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f89059e826040518263ffffffff1660e01b8152600401610da491906127d0565b60206040518083038186803b158015610dbc57600080fd5b505afa158015610dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df491906120cd565b610e33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2a90612863565b60405180910390fd5b610e3e816000611028565b9450610e6b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168888611443565b50809350508273ffffffffffffffffffffffffffffffffffffffff168585604051602001610e9a929190612669565b604051602081830303815290604052805190602001207fa2e66ce20e6fb2c4f61339c364ad79f15160cf5307230c8bc4d628adbca2ba3989604051610edf91906127d0565b60405180910390a350509250925092565b6000828281518110610f2b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602001015160f81c60f81b60f81c905092915050565b600083518284610f519190612a0c565b1115610f5c57600080fd5b818360208601012090509392505050565b606083518284610f7d9190612a0c565b1115610f8857600080fd5b60008267ffffffffffffffff811115610fca577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015610ffc5781602001600182028036833780820191505090505b509050600080602083019150856020880101905061101b8282876116b4565b8293505050509392505050565b60008061103e8385610ef090919063ffffffff16565b60ff1690506000811415611058576000801b91505061143d565b600061107b856001848761106c9190612a0c565b6110769190612a0c565b611028565b905060006110a060018661108f9190612a0c565b8488610f419092919063ffffffff16565b905081816040516020016110b5929190612669565b6040516020818303038152906040528051906020012093506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3866040518263ffffffff1660e01b815260040161112a9190612702565b60206040518083038186803b15801561114257600080fd5b505afa158015611156573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117a91906120a4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806111e257503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611221576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121890612883565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611438576000801b831415611384576000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be36000801b6040518263ffffffff1660e01b81526004016112bf9190612702565b60206040518083038186803b1580156112d757600080fd5b505afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f91906120a4565b90508073ffffffffffffffffffffffffffffffffffffffff16638cb8ecec84306040518363ffffffff1660e01b815260040161134c92919061271d565b600060405180830381600087803b15801561136657600080fd5b505af115801561137a573d6000803e3d6000fd5b5050505050611437565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59238484306040518463ffffffff1660e01b81526004016113e393929190612746565b602060405180830381600087803b1580156113fd57600080fd5b505af1158015611411573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143591906120f6565b505b5b505050505b92915050565b60008061144e611d86565b61146e6005865161145f9190612a0c565b8261171890919063ffffffff16565b506114b76040518060400160405280600581526020017f045f656e730000000000000000000000000000000000000000000000000000008152508261178290919063ffffffff16565b506114cb858261178290919063ffffffff16565b506000808773ffffffffffffffffffffffffffffffffffffffff1663087991bc601085600001516040518363ffffffff1660e01b815260040161150f9291906128e3565b60606040518083038186803b15801561152757600080fd5b505afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f919061239d565b9091508093508192505050600060601b6bffffffffffffffffffffffff1916826bffffffffffffffffffffffff191614801561159c575060008651145b156115b057600080945094505050506116ac565b85805190602001206bffffffffffffffffffffffff1916826bffffffffffffffffffffffff1916146115e157600080fd5b60006115f76000886117a490919063ffffffff16565b90505b611603816117ce565b6116a05761162081608001518361161a9190612a62565b426117e4565b61165f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611656906128a3565b60405180910390fd5b600080611670898460a00151611800565b8093508192505050811561169057806001975097505050505050506116ac565b505061169b81611886565b6115fa565b50600080945094505050505b935093915050565b5b602081106116f357815183526020836116ce9190612a0c565b92506020826116dd9190612a0c565b91506020816116ec9190612b6e565b90506116b5565b60006001826020036101000a0390508019835116818551168181178652505050505050565b611720611d86565b600060208361172f9190612df3565b1461175b576020826117419190612df3565b602061174d9190612b6e565b826117589190612a0c565b91505b81836020018181525050604051808452600081528281016020016040525082905092915050565b61178a611d86565b61179c838460000151518485516119d0565b905092915050565b6117ac611da0565b828160000181905250818160c00181815250506117c881611886565b92915050565b6000816000015151826020015110159050919050565b60008082846117f39190612af6565b60030b1215905092915050565b6000805b83518310156118775760006118228486610ef090919063ffffffff16565b60ff1690506001846118349190612a0c565b9350600080611844878785611abf565b80935081925050508115611861578060019450945050505061187f565b828661186d9190612a0c565b9550505050611804565b600080915091505b9250929050565b8060c001518160200181815250508060000151518160200151106118a9576119cd565b60006118bd82600001518360200151611b29565b82602001516118cc9190612a0c565b90506118e5818360000151611bcc90919063ffffffff16565b826040019061ffff16908161ffff16815250506002816119059190612a0c565b905061191e818360000151611bcc90919063ffffffff16565b826060019061ffff16908161ffff168152505060028161193e9190612a0c565b9050611957818360000151611bfb90919063ffffffff16565b826080019063ffffffff16908163ffffffff168152505060048161197b9190612a0c565b90506000611996828460000151611bcc90919063ffffffff16565b61ffff1690506002826119a99190612a0c565b9150818360a001818152505080826119c19190612a0c565b8360c001818152505050505b50565b6119d8611d86565b82518211156119e657600080fd5b846020015182856119f79190612a0c565b1115611a2c57611a2b856002611a1c88602001518887611a179190612a0c565b611c2c565b611a269190612a9c565b611c48565b5b600080865180518760208301019350808887011115611a4b5787860182525b60208701925050505b60208410611a925780518252602082611a6d9190612a0c565b9150602081611a7c9190612a0c565b9050602084611a8b9190612b6e565b9350611a54565b60006001856020036101000a03905080198251168184511681811785525050508692505050949350505050565b60008063613d3078611ada8587611bfb90919063ffffffff16565b63ffffffff1614611af15760008091509150611b21565b602c831015611b065760008091509150611b21565b611b1c85600486611b179190612a0c565b611c6c565b915091505b935093915050565b6000808290505b600115611bb75783518110611b6e577f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000611b838286610ef090919063ffffffff16565b60ff169050600181611b959190612a0c565b82611ba09190612a0c565b91506000811415611bb15750611bb7565b50611b30565b8281611bc39190612b6e565b91505092915050565b60008251600283611bdd9190612a0c565b1115611be857600080fd5b61ffff8260028501015116905092915050565b60008251600483611c0c9190612a0c565b1115611c1757600080fd5b63ffffffff8260048501015116905092915050565b600081831115611c3e57829050611c42565b8190505b92915050565b600082600001519050611c5b8383611718565b50611c668382611782565b50505050565b6000806028838551611c7e9190612b6e565b1015611c905760008091509150611d7f565b6000808490505b602885611ca49190612a0c565b811015611d7557600482901b91506000611cc78288610ef090919063ffffffff16565b60ff16905060308110158015611cdd5750603a81105b15611cf857603081611cef9190612b6e565b83179250611d61565b60418110158015611d095750604781105b15611d2457603781611d1b9190612b6e565b83179250611d60565b60618110158015611d355750606781105b15611d5057605781611d479190612b6e565b83179250611d5f565b60008094509450505050611d7f565b5b5b508080611d6d90612da0565b915050611c97565b5080600192509250505b9250929050565b604051806040016040528060608152602001600081525090565b6040518060e001604052806060815260200160008152602001600061ffff168152602001600061ffff168152602001600063ffffffff16815260200160008152602001600081525090565b6000611dfe611df984612938565b612913565b90508083825260208201905082856020860282011115611e1d57600080fd5b60005b85811015611e6757813567ffffffffffffffff811115611e3f57600080fd5b808601611e4c8982612013565b85526020850194506020840193505050600181019050611e20565b5050509392505050565b6000611e84611e7f84612964565b612913565b905082815260208101848484011115611e9c57600080fd5b611ea7848285612d2d565b509392505050565b6000611ec2611ebd84612964565b612913565b905082815260208101848484011115611eda57600080fd5b611ee5848285612d3c565b509392505050565b600081359050611efc8161304d565b92915050565b600081519050611f118161304d565b92915050565b600082601f830112611f2857600080fd5b8135611f38848260208601611deb565b91505092915050565b600081519050611f5081613064565b92915050565b600081519050611f658161307b565b92915050565b600081519050611f7a81613092565b92915050565b600081359050611f8f816130a9565b92915050565b600082601f830112611fa657600080fd5b8135611fb6848260208601611e71565b91505092915050565b600082601f830112611fd057600080fd5b8151611fe0848260208601611eaf565b91505092915050565b600081359050611ff8816130c0565b92915050565b60008135905061200d816130d7565b92915050565b60006040828403121561202557600080fd5b61202f6040612913565b9050600082013567ffffffffffffffff81111561204b57600080fd5b61205784828501611f95565b600083015250602082013567ffffffffffffffff81111561207757600080fd5b61208384828501611f95565b60208301525092915050565b60008151905061209e816130ee565b92915050565b6000602082840312156120b657600080fd5b60006120c484828501611f02565b91505092915050565b6000602082840312156120df57600080fd5b60006120ed84828501611f41565b91505092915050565b60006020828403121561210857600080fd5b600061211684828501611f6b565b91505092915050565b60006020828403121561213157600080fd5b600061213f84828501611f80565b91505092915050565b60006020828403121561215a57600080fd5b600082015167ffffffffffffffff81111561217457600080fd5b61218084828501611fbf565b91505092915050565b60008060006060848603121561219e57600080fd5b600084013567ffffffffffffffff8111156121b857600080fd5b6121c486828701611f95565b935050602084013567ffffffffffffffff8111156121e157600080fd5b6121ed86828701611f17565b925050604084013567ffffffffffffffff81111561220a57600080fd5b61221686828701611f95565b9150509250925092565b600080600080600060a0868803121561223857600080fd5b600086013567ffffffffffffffff81111561225257600080fd5b61225e88828901611f95565b955050602086013567ffffffffffffffff81111561227b57600080fd5b61228788828901611f17565b945050604086013567ffffffffffffffff8111156122a457600080fd5b6122b088828901611f95565b93505060606122c188828901611eed565b92505060806122d288828901611eed565b9150509295509295909350565b600080604083850312156122f257600080fd5b600083013567ffffffffffffffff81111561230c57600080fd5b61231885828601611f95565b925050602083013567ffffffffffffffff81111561233557600080fd5b61234185828601611f95565b9150509250929050565b60006020828403121561235d57600080fd5b600061236b84828501611fe9565b91505092915050565b60006020828403121561238657600080fd5b600061239484828501611ffe565b91505092915050565b6000806000606084860312156123b257600080fd5b60006123c08682870161208f565b93505060206123d18682870161208f565b92505060406123e286828701611f56565b9150509250925092565b60006123f88383612616565b905092915050565b61240981612ba2565b82525050565b600061241a826129a5565b61242481856129c8565b93508360208202850161243685612995565b8060005b85811015612472578484038952815161245385826123ec565b945061245e836129bb565b925060208a0199505060018101905061243a565b50829750879550505050505092915050565b61248d81612bb4565b82525050565b61249c81612bec565b82525050565b6124b36124ae82612bec565b612de9565b82525050565b60006124c4826129b0565b6124ce81856129d9565b93506124de818560208601612d3c565b6124e781612eb1565b840191505092915050565b60006124fd826129b0565b61250781856129ea565b9350612517818560208601612d3c565b61252081612eb1565b840191505092915050565b61253481612caf565b82525050565b61254381612cd3565b82525050565b61255281612cf7565b82525050565b61256181612d1b565b82525050565b60006125746026836129fb565b915061257f82612ec2565b604082019050919050565b60006125976023836129fb565b91506125a282612f11565b604082019050919050565b60006125ba602a836129fb565b91506125c582612f60565b604082019050919050565b60006125dd603c836129fb565b91506125e882612faf565b604082019050919050565b6000612600602d836129fb565b915061260b82612ffe565b604082019050919050565b6000604083016000830151848203600086015261263382826124b9565b9150506020830151848203602086015261264d82826124b9565b9150508091505092915050565b61266381612c53565b82525050565b600061267582856124a2565b60208201915061268582846124a2565b6020820191508190509392505050565b60006020820190506126aa6000830184612400565b92915050565b600060408201905081810360008301526126ca818561240f565b905081810360208301526126de81846124f2565b90509392505050565b60006020820190506126fc6000830184612484565b92915050565b60006020820190506127176000830184612493565b92915050565b60006040820190506127326000830185612493565b61273f6020830184612400565b9392505050565b600060608201905061275b6000830186612493565b6127686020830185612493565b6127756040830184612400565b949350505050565b600060a0820190506127926000830188612493565b61279f6020830187612493565b6127ac6040830186612400565b6127b96060830185612400565b6127c66080830184612558565b9695505050505050565b600060208201905081810360008301526127ea81846124f2565b905092915050565b6000602082019050612807600083018461252b565b92915050565b6000602082019050612822600083018461253a565b92915050565b600060208201905061283d6000830184612549565b92915050565b6000602082019050818103600083015261285c81612567565b9050919050565b6000602082019050818103600083015261287c8161258a565b9050919050565b6000602082019050818103600083015261289c816125ad565b9050919050565b600060208201905081810360008301526128bc816125d0565b9050919050565b600060208201905081810360008301526128dc816125f3565b9050919050565b60006040820190506128f8600083018561265a565b818103602083015261290a81846124f2565b90509392505050565b600061291d61292e565b90506129298282612d6f565b919050565b6000604051905090565b600067ffffffffffffffff82111561295357612952612e82565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561297f5761297e612e82565b5b61298882612eb1565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000612a1782612c81565b9150612a2283612c81565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612a5757612a56612e24565b5b828201905092915050565b6000612a6d82612c8b565b9150612a7883612c8b565b92508263ffffffff03821115612a9157612a90612e24565b5b828201905092915050565b6000612aa782612c81565b9150612ab283612c81565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612aeb57612aea612e24565b5b828202905092915050565b6000612b0182612c46565b9150612b0c83612c46565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000001821260008412151615612b4757612b46612e24565b5b82637fffffff018213600084121615612b6357612b62612e24565b5b828203905092915050565b6000612b7982612c81565b9150612b8483612c81565b925082821015612b9757612b96612e24565b5b828203905092915050565b6000612bad82612c61565b9050919050565b60008115159050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000612c2d82612ba2565b9050919050565b6000612c3f82612ba2565b9050919050565b60008160030b9050919050565b600061ffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600067ffffffffffffffff82169050919050565b6000612cba82612cc1565b9050919050565b6000612ccc82612c61565b9050919050565b6000612cde82612ce5565b9050919050565b6000612cf082612c61565b9050919050565b6000612d0282612d09565b9050919050565b6000612d1482612c61565b9050919050565b6000612d2682612c9b565b9050919050565b82818337600083830152505050565b60005b83811015612d5a578082015181840152602081019050612d3f565b83811115612d69576000848401525b50505050565b612d7882612eb1565b810181811067ffffffffffffffff82111715612d9757612d96612e82565b5b80604052505050565b6000612dab82612c81565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612dde57612ddd612e24565b5b600182019050919050565b6000819050919050565b6000612dfe82612c81565b9150612e0983612c81565b925082612e1957612e18612e53565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f43616e6e6f74207365742061646472206966207265736f6c766572206973206e60008201527f6f74207365740000000000000000000000000000000000000000000000000000602082015250565b7f506172656e74206e616d65206d7573742062652061207075626c69632073756660008201527f6669780000000000000000000000000000000000000000000000000000000000602082015250565b7f43616e6e6f7420656e61626c652061206e616d65206f776e656420627920736f60008201527f6d656f6e6520656c736500000000000000000000000000000000000000000000602082015250565b7f444e53207265636f7264206973207374616c653b2072656672657368206f722060008201527f64656c657465206974206265666f72652070726f63656564696e672e00000000602082015250565b7f4f6e6c79206f776e65722063616e2063616c6c2070726f7665416e64436c616960008201527f6d576974685265736f6c76657200000000000000000000000000000000000000602082015250565b61305681612ba2565b811461306157600080fd5b50565b61306d81612bb4565b811461307857600080fd5b50565b61308481612bc0565b811461308f57600080fd5b50565b61309b81612bec565b81146130a657600080fd5b50565b6130b281612bf6565b81146130bd57600080fd5b50565b6130c981612c22565b81146130d457600080fd5b50565b6130e081612c34565b81146130eb57600080fd5b50565b6130f781612c8b565b811461310257600080fd5b5056fea26469706673582212206ee5cab83a909097227319cce5a4b719af0f19534dc0e6e62503c5f38a59e2e764736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000046c6f79952d3046bf673a28132ff2a81f306959c000000000000000000000000d10730069066cda980edfb5e70ef678a38b5265f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e
-----Decoded View---------------
Arg [0] : _dnssec (address): 0x46c6F79952d3046Bf673a28132ff2a81F306959c
Arg [1] : _suffixes (address): 0xD10730069066cda980eDFb5e70eF678a38b5265F
Arg [2] : _ens (address): 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000046c6f79952d3046bf673a28132ff2a81f306959c
Arg [1] : 000000000000000000000000d10730069066cda980edfb5e70ef678a38b5265f
Arg [2] : 00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.