编译器
0.8.24+commit.e11b9ed9
文件 1 的 9:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 2 的 9:IDomainPricer.sol
pragma solidity ^0.8.24;
interface IDomainPricer {
function getUpdatePrice(
uint256 lastRegPrice,
uint256 lastRegTimeSec
) external returns (uint256 value);
function getPrice(
uint256 lastRegPrice,
uint256 lastRegTimeSec
) external view returns (uint256 value);
}
文件 3 的 9:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 4 的 9:IERC721.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 5 的 9:ILockBox.sol
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
interface ILockBox is IERC721 {
function lockups(
uint256 lockupId
)
external
view
returns (
uint256 amountAsset,
uint256 amountLpToken,
uint256 lpTokenValuation,
uint256 assetSecondsLocked,
uint256 lpSecondsLocked,
uint64 createTime,
uint64 lastDepositTime,
uint64 durationSeconds,
bool autoRelock
);
}
文件 6 的 9:IPNS.sol
pragma solidity ^0.8.24;
import "../external/ILockBox.sol";
interface IPNS {
event Preregister(address sender, bytes32 nameHash, uint64 lockupId);
event DestroyPrereg(address sender, bytes32 nameHash, uint64 lockupId);
event Register(address sender, uint64 id, uint64 lockupId, bytes name, bytes records);
event UpdateRecords(address sender, uint64 id, bytes records);
event Takeover(address sender, uint64 id, uint64 oldLockupId, uint64 newLockupId, bytes records);
event CreateSubdomain(address sender, uint64 id, uint64 parentId, bytes name, bytes records);
event Destroy(address sender, uint64 id);
event Blacklist(address sender, uint64 id, bool isBlacklisted);
struct Domain {
uint64 owner;
uint8 subdomains;
bool blacklisted;
bytes name;
bytes records;
}
function lockboxContract() external returns (ILockBox);
function currentMinLockup() external view returns (uint256 price);
function getLockupValuation(uint256 lockupId) external view returns (uint256);
function computePreregHash(
uint64 lockupId,
bytes calldata name,
bytes calldata records
) external pure returns (bytes32);
function preregister(bytes32 nameHash, uint64 lockupId) external;
function destroyPrereg(bytes32 nameHash, uint64 lockupId) external;
function register(
uint64 lockupId,
bytes calldata name,
bytes calldata records
) external;
function ownerLockup(uint64 id) external view returns (uint64);
function authorizedFor(uint64 id, address who) external view returns (bool);
function updateRecords(
uint64 id,
bytes calldata records
) external;
function takeover(
uint64 id,
uint64 newLockupId,
bytes calldata records
) external;
function createSubdomain(
uint64 parentId,
bytes calldata subdomainLabel,
bytes calldata records
) external;
function destroy(uint64 id) external;
struct NewSubdomain {
uint64 parentId;
bytes subdomainLabel;
bytes records;
}
struct RecordUpdate {
uint64 id;
bytes records;
}
function updateMultiple(
NewSubdomain[] calldata newSubdomains,
RecordUpdate[] calldata recordUpdates,
uint64[] calldata destroyDomains
) external;
function nextDomainId() external view returns (uint);
function domainIdFreeList(uint64 last) external view returns (uint);
function getDomain(uint64 id) external view returns (
uint64 owner,
uint8 subdomains,
bool blacklisted,
bytes memory name,
bytes memory records
);
function getDomains(uint64[] calldata ids) external view returns (Domain[] memory out);
function getDomainIdByLockupId(uint64 lockupId) external view returns (uint64);
function getDomainIdByFQDN(bytes calldata fqdn) external view returns (uint64);
function getPricingInfo() external view returns (
address pricer,
uint64 lastRegTime,
uint256 lastRegPrice
);
function getPrereg(bytes32 nameHash) external view returns (
uint64 timestamp,
uint64 lockupId
);
function isAddressWhitelisted(address addr) external view returns (bool);
function isRegistrationWhitelistActive() external view returns (bool);
function getAdmin() external view returns (address);
function setAdmin(address admin) external;
function setPricer(address pricer) external;
function setLockbox(address lbox) external;
struct AllowedAddress {
address addr;
bool allowed;
}
function updateRegistrationWhitelist(AllowedAddress[] calldata allowed, bool activate) external;
function setDomainBlacklisted(uint64 id, bool blacklisted) external;
}
文件 7 的 9:IdProvider.sol
pragma solidity ^0.8.24;
library IdProvider {
struct Ids {
mapping(uint => uint) freeList;
uint nextId;
}
function init(Ids storage self) internal {
self.nextId = 1;
}
function take(Ids storage self) internal returns (uint id) {
id = self.freeList[0];
if (id > 0) {
self.freeList[0] = self.freeList[id];
delete self.freeList[id];
} else {
id = self.nextId++;
}
}
function release(Ids storage self, uint id) internal {
uint fdid = self.freeList[0];
if (fdid > 0) {
self.freeList[id] = fdid;
}
self.freeList[0] = id;
}
}
文件 8 的 9:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 9 的 9:PNS.sol
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./external/ILockBox.sol";
import "./interface/IPNS.sol";
import "./interface/IDomainPricer.sol";
import "./libraries/IdProvider.sol";
contract PNS is Ownable, IPNS {
using IdProvider for IdProvider.Ids;
uint64 public constant PREREG_LIFETIME_SECONDS = 60*60*24;
ILockBox private self_lockboxContract;
IdProvider.Ids private self_ids;
uint64 private self_lastRegTimeSec;
uint256 private self_lastRegPrice = 1;
IDomainPricer private self_pricer;
mapping(uint64 => Domain) private self_domainById;
mapping(uint64 => uint64) private self_domainByLockupId;
mapping(bytes => uint64) private self_domainByFQDN;
struct Prereg {
uint64 timestamp;
uint64 lockupId;
}
mapping(bytes32 => Prereg) private self_preregs;
mapping(address => bool) private self_registrationWhitelist;
bool private self_registrationWhitelistActive;
address private self_admin;
constructor(ILockBox _lockboxContract, bool _whitelistActive, address pricer) Ownable(msg.sender) {
self_lockboxContract = _lockboxContract;
self_registrationWhitelistActive = _whitelistActive;
self_admin = msg.sender;
self_ids.init();
self_pricer = IDomainPricer(pricer);
}
function currentMinLockup() external view override returns (uint256 price) {
return self_pricer.getPrice(self_lastRegPrice, self_lastRegTimeSec);
}
function getLockupValuation(uint256 lockupId) public override view returns (uint256) {
(
uint256 amountAsset,
,
uint256 lpTokenValuation,
,
,
,
,
,
) = self_lockboxContract.lockups(lockupId);
return amountAsset + lpTokenValuation;
}
function computePreregHash(
uint64 lockupId,
bytes calldata name,
bytes calldata records
) public override pure returns (bytes32) {
return keccak256(abi.encode(name,lockupId,records));
}
function preregister(bytes32 nameHash, uint64 lockupId) external override {
_checkAuthorizedForLockup(msg.sender, lockupId);
require(self_domainByLockupId[lockupId] == 0, "Lockup already used for another domain");
if (self_registrationWhitelistActive) {
require(self_registrationWhitelist[msg.sender], "Only whitelisted addresses can register at this time");
}
{
uint256 value = getLockupValuation(lockupId);
require(value >= getUpdateCurrentMinLockup(), "Lockup does not have enough value of assets");
self_lastRegTimeSec = uint64(block.timestamp);
self_lastRegPrice = value;
}
{
Prereg storage pr = self_preregs[nameHash];
pr.lockupId = lockupId;
pr.timestamp = uint64(block.timestamp);
}
emit Preregister(msg.sender, nameHash, lockupId);
}
function destroyPrereg(bytes32 nameHash, uint64 lockupId) external override {
Prereg storage pr = self_preregs[nameHash];
require(pr.lockupId == lockupId, "Mismatching lockup id");
if (uint64(block.timestamp) < pr.timestamp + PREREG_LIFETIME_SECONDS) {
uint256 value = getLockupValuation(lockupId);
if (value > 0) {
_checkAuthorizedForLockup(msg.sender, lockupId);
}
}
delete self_preregs[nameHash];
emit DestroyPrereg(msg.sender, nameHash, lockupId);
}
function register(
uint64 lockupId,
bytes calldata name,
bytes calldata records
) external override {
require(name.length > 0, "Name cannot be empty");
for (uint i = 0; i < name.length; i++) {
require(name[i] != '.', "Names cannot have dots in them");
}
{
bytes32 nameHash = computePreregHash(lockupId, name, records);
Prereg memory pr = self_preregs[nameHash];
require(pr.lockupId == lockupId, "Must use same lockup when registering as preregistering");
require(block.timestamp > pr.timestamp && block.timestamp < pr.timestamp + PREREG_LIFETIME_SECONDS,
"Domain must be pre-registered first");
delete self_preregs[nameHash];
}
{
uint256 value = getLockupValuation(lockupId);
require(value > 0, "Cannot register a domain with a lockup which has been released");
}
require(self_domainByLockupId[lockupId] == 0, "Lockbox already used for another domain");
require(self_domainByFQDN[name] == 0, "Domain already registered");
{
uint64 id = uint64(self_ids.take());
Domain storage dom = self_domainById[id];
dom.name = name;
dom.owner = lockupId;
dom.records = records;
dom.subdomains = 0;
dom.blacklisted = false;
self_domainByLockupId[lockupId] = id;
self_domainByFQDN[name] = id;
emit Register(msg.sender, id, lockupId, name, records);
}
}
function ownerLockup(uint64 id) public view override returns (uint64) {
Domain memory dom = self_domainById[id];
require(self_domainByFQDN[dom.name] == id, "Domain does not exist");
uint64 owner = dom.owner;
if (dom.subdomains == 0xff) {
owner = self_domainById[dom.owner].owner;
}
return owner;
}
function authorizedFor(uint64 id, address who) public view override returns (bool) {
uint64 lockupId = ownerLockup(id);
return _isAuthorizedForLockup(who, lockupId);
}
function updateRecords(
uint64 id,
bytes calldata records
) public override {
Domain storage dom = self_domainById[id];
require(self_domainByFQDN[dom.name] == id, "Domain does not exist");
uint64 owner = dom.owner;
if (dom.subdomains == 0xff) {
owner = self_domainById[dom.owner].owner;
}
_checkAuthorizedForLockup(msg.sender, owner);
dom.records = records;
emit UpdateRecords(msg.sender, id, records);
}
function takeover(
uint64 id,
uint64 newLockupId,
bytes calldata records
) external override {
{
uint256 value = getLockupValuation(newLockupId);
require(value >= getUpdateCurrentMinLockup(), "Lockup does not have enough value of assets");
self_lastRegTimeSec = uint64(block.timestamp);
self_lastRegPrice = value;
}
{
Domain storage dom = self_domainById[id];
require(self_domainByFQDN[dom.name] == id, "Domain does not exist");
require(dom.subdomains < 0xff, "Can't takeover a subdomain");
uint64 oldLockupId = dom.owner;
require(getLockupValuation(oldLockupId) == 0 || _isAuthorizedForLockup(msg.sender, oldLockupId),
"Can only takeover a domain if the lockup was released or you're authorized by the owner");
dom.owner = newLockupId;
if (records.length > 0) {
dom.records = records;
}
emit Takeover(msg.sender, id, oldLockupId, newLockupId, records);
}
}
function createSubdomain(
uint64 parentId,
bytes calldata subdomainLabel,
bytes calldata records
) public override {
bytes memory fqdn;
bool blacklisted;
{
Domain storage dom = self_domainById[parentId];
require(self_domainByFQDN[dom.name] == parentId, "Parent domain does not exist");
require(dom.subdomains < 0xfe, "Can't make a subdomain of a subdomain");
_checkAuthorizedForLockup(msg.sender, dom.owner);
dom.subdomains++;
fqdn = bytes.concat(subdomainLabel, bytes("."), dom.name);
blacklisted = dom.blacklisted;
require(self_domainByFQDN[fqdn] == 0, "Subdomain already exists");
}
{
uint64 id = uint64(self_ids.take());
self_domainByFQDN[fqdn] = id;
Domain storage dom = self_domainById[id];
dom.subdomains = 0xff;
dom.name = fqdn;
dom.owner = parentId;
dom.records = records;
dom.blacklisted = blacklisted;
emit CreateSubdomain(msg.sender, id, parentId, fqdn, records);
}
}
function destroy(uint64 id) public override {
Domain storage dom = self_domainById[id];
require(self_domainByFQDN[dom.name] == id, "Domain does not exist");
uint64 lockup;
if (dom.subdomains == 0xff) {
Domain storage parent = self_domainById[dom.owner];
lockup = parent.owner;
parent.subdomains--;
} else {
require(dom.subdomains == 0, "Can't destroy a domain which still has subdomains");
lockup = dom.owner;
delete self_domainByLockupId[lockup];
}
if (!_isAuthorizedForLockup(msg.sender, lockup)) {
uint256 value = getLockupValuation(lockup);
require(value == 0, "Cannot destroy someone else's domain unless their lockup is released");
}
delete self_domainByFQDN[dom.name];
delete self_domainById[id];
self_ids.release(id);
emit Destroy(msg.sender, id);
}
function updateMultiple(
NewSubdomain[] calldata newSubdomains,
RecordUpdate[] calldata recordUpdates,
uint64[] calldata destroyDomains
) external override {
for (uint8 i = 0; i < newSubdomains.length; i++) {
NewSubdomain calldata ns = newSubdomains[i];
createSubdomain(ns.parentId, ns.subdomainLabel, ns.records);
}
for (uint8 i = 0; i < recordUpdates.length; i++) {
RecordUpdate calldata ru = recordUpdates[i];
updateRecords(ru.id, ru.records);
}
for (uint8 i = 0; i < destroyDomains.length; i++) {
destroy(destroyDomains[i]);
}
}
function lockboxContract() external override view returns (ILockBox) {
return self_lockboxContract;
}
function nextDomainId() external override view returns (uint) {
return self_ids.nextId;
}
function domainIdFreeList(uint64 last) external override view returns (uint) {
return self_ids.freeList[last];
}
function getDomain(uint64 id) external override view returns (
uint64 owner,
uint8 subdomains,
bool blacklisted,
bytes memory name,
bytes memory records
) {
Domain memory dom = self_domainById[id];
owner = dom.owner;
name = dom.name;
records = dom.records;
subdomains = dom.subdomains;
blacklisted = dom.blacklisted;
}
function getDomains(uint64[] calldata ids) external override view returns (Domain[] memory out) {
out = new Domain[](ids.length);
for (uint i = 0; i < ids.length; i++) {
out[i] = self_domainById[ids[i]];
}
}
function getDomainIdByLockupId(uint64 lockupId) external override view returns (uint64) {
return self_domainByLockupId[lockupId];
}
function getDomainIdByFQDN(bytes calldata fqdn) external override view returns (uint64) {
return self_domainByFQDN[fqdn];
}
function getPricingInfo() external override view returns (
address pricer,
uint64 lastRegTime,
uint256 lastRegPrice
) {
pricer = address(self_pricer);
lastRegTime = self_lastRegTimeSec;
lastRegPrice = self_lastRegPrice;
}
function getPrereg(bytes32 nameHash) external override view returns (
uint64 timestamp,
uint64 lockupId
) {
Prereg memory pr = self_preregs[nameHash];
lockupId = pr.lockupId;
timestamp = pr.timestamp;
}
function isAddressWhitelisted(address addr) external override view returns (bool) {
return self_registrationWhitelist[addr];
}
function isRegistrationWhitelistActive() external override view returns (bool) {
return self_registrationWhitelistActive;
}
function getAdmin() external override view returns (address) {
return self_admin;
}
function setAdmin(address admin) external override onlyOwner {
self_admin = admin;
}
function setPricer(address pricer) external override {
require(msg.sender == self_admin, "Admin only");
self_pricer = IDomainPricer(pricer);
}
function setLockbox(address lbox) external override {
require(msg.sender == self_admin, "Admin only");
self_lockboxContract = ILockBox(lbox);
}
function updateRegistrationWhitelist(AllowedAddress[] calldata allowed, bool activate) external override {
require(msg.sender == self_admin, "Admin only");
for (uint8 i = 0; i < allowed.length; i++) {
if (allowed[i].allowed) {
self_registrationWhitelist[allowed[i].addr] = true;
} else {
delete self_registrationWhitelist[allowed[i].addr];
}
}
self_registrationWhitelistActive = activate;
}
function setDomainBlacklisted(uint64 id, bool blacklisted) external override {
require(msg.sender == self_admin, "Admin only");
Domain storage dom = self_domainById[id];
require(self_domainByFQDN[dom.name] == id, "Domain does not exist");
dom.blacklisted = blacklisted;
emit Blacklist(msg.sender, id, blacklisted);
}
function _isAuthorizedForLockup(address who, uint64 lockupId) private view returns (bool) {
address owner = self_lockboxContract.ownerOf(lockupId);
if (owner == who) {
return true;
}
if (self_lockboxContract.getApproved(lockupId) == who) {
return true;
}
return self_lockboxContract.isApprovedForAll(owner, who);
}
function _checkAuthorizedForLockup(address who, uint64 lockupId) private view {
require(_isAuthorizedForLockup(who, lockupId), "Unauthorized");
}
function getUpdateCurrentMinLockup() private returns (uint256 price) {
return self_pricer.getUpdatePrice(self_lastRegPrice, self_lastRegTimeSec);
}
}
{
"compilationTarget": {
"contracts/PNS.sol": "PNS"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"contract ILockBox","name":"_lockboxContract","type":"address"},{"internalType":"bool","name":"_whitelistActive","type":"bool"},{"internalType":"address","name":"pricer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"id","type":"uint64"},{"indexed":false,"internalType":"bool","name":"isBlacklisted","type":"bool"}],"name":"Blacklist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"id","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"parentId","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"records","type":"bytes"}],"name":"CreateSubdomain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"id","type":"uint64"}],"name":"Destroy","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes32","name":"nameHash","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"lockupId","type":"uint64"}],"name":"DestroyPrereg","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes32","name":"nameHash","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"lockupId","type":"uint64"}],"name":"Preregister","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"id","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"lockupId","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"records","type":"bytes"}],"name":"Register","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"id","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"oldLockupId","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"newLockupId","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"records","type":"bytes"}],"name":"Takeover","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"id","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"records","type":"bytes"}],"name":"UpdateRecords","type":"event"},{"inputs":[],"name":"PREREG_LIFETIME_SECONDS","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"id","type":"uint64"},{"internalType":"address","name":"who","type":"address"}],"name":"authorizedFor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"lockupId","type":"uint64"},{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"records","type":"bytes"}],"name":"computePreregHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"parentId","type":"uint64"},{"internalType":"bytes","name":"subdomainLabel","type":"bytes"},{"internalType":"bytes","name":"records","type":"bytes"}],"name":"createSubdomain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentMinLockup","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"id","type":"uint64"}],"name":"destroy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"nameHash","type":"bytes32"},{"internalType":"uint64","name":"lockupId","type":"uint64"}],"name":"destroyPrereg","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"last","type":"uint64"}],"name":"domainIdFreeList","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"id","type":"uint64"}],"name":"getDomain","outputs":[{"internalType":"uint64","name":"owner","type":"uint64"},{"internalType":"uint8","name":"subdomains","type":"uint8"},{"internalType":"bool","name":"blacklisted","type":"bool"},{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"records","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"fqdn","type":"bytes"}],"name":"getDomainIdByFQDN","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"lockupId","type":"uint64"}],"name":"getDomainIdByLockupId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"ids","type":"uint64[]"}],"name":"getDomains","outputs":[{"components":[{"internalType":"uint64","name":"owner","type":"uint64"},{"internalType":"uint8","name":"subdomains","type":"uint8"},{"internalType":"bool","name":"blacklisted","type":"bool"},{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"records","type":"bytes"}],"internalType":"struct IPNS.Domain[]","name":"out","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockupId","type":"uint256"}],"name":"getLockupValuation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"nameHash","type":"bytes32"}],"name":"getPrereg","outputs":[{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"lockupId","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPricingInfo","outputs":[{"internalType":"address","name":"pricer","type":"address"},{"internalType":"uint64","name":"lastRegTime","type":"uint64"},{"internalType":"uint256","name":"lastRegPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isAddressWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRegistrationWhitelistActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockboxContract","outputs":[{"internalType":"contract ILockBox","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextDomainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"id","type":"uint64"}],"name":"ownerLockup","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"nameHash","type":"bytes32"},{"internalType":"uint64","name":"lockupId","type":"uint64"}],"name":"preregister","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"lockupId","type":"uint64"},{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"records","type":"bytes"}],"name":"register","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"id","type":"uint64"},{"internalType":"bool","name":"blacklisted","type":"bool"}],"name":"setDomainBlacklisted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lbox","type":"address"}],"name":"setLockbox","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pricer","type":"address"}],"name":"setPricer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"id","type":"uint64"},{"internalType":"uint64","name":"newLockupId","type":"uint64"},{"internalType":"bytes","name":"records","type":"bytes"}],"name":"takeover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"parentId","type":"uint64"},{"internalType":"bytes","name":"subdomainLabel","type":"bytes"},{"internalType":"bytes","name":"records","type":"bytes"}],"internalType":"struct IPNS.NewSubdomain[]","name":"newSubdomains","type":"tuple[]"},{"components":[{"internalType":"uint64","name":"id","type":"uint64"},{"internalType":"bytes","name":"records","type":"bytes"}],"internalType":"struct IPNS.RecordUpdate[]","name":"recordUpdates","type":"tuple[]"},{"internalType":"uint64[]","name":"destroyDomains","type":"uint64[]"}],"name":"updateMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"id","type":"uint64"},{"internalType":"bytes","name":"records","type":"bytes"}],"name":"updateRecords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"allowed","type":"bool"}],"internalType":"struct IPNS.AllowedAddress[]","name":"allowed","type":"tuple[]"},{"internalType":"bool","name":"activate","type":"bool"}],"name":"updateRegistrationWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"}]