DotnsRegistry

Git Source

Inherits: Initializable, UUPSUpgradeable, OwnableUpgradeable, IDotnsRegistry

Title: Dotns Registry

Author: Parity

Upgradeable on-chain registry for hierarchical name ownership and resolution.

Tokenised second-level nodes store owner == address(0) as a sentinel and defer to IDotnsRegistrar.ownerOf; subnodes carry an explicit owner address in records.

Note: security-contact: admin@parity.io

State Variables

records

Mapping of node identifiers to records.

mapping(bytes32 node => Record record) private records

protocolRegistry

Protocol-level address registry for all DotNS contracts.

IDotnsProtocolRegistry public protocolRegistry

__gap

uint256[50] private __gap

Functions

authorised

Restricts access to the current owner of node.

modifier authorised(bytes32 node) ;

onlyRegistrarController

Restricts access to the configured registrar controller.

modifier onlyRegistrarController() ;

constructor

Note: oz-upgrades-unsafe-allow: constructor

constructor() ;

initialize

Initialises the registry.

Callable exactly once via Initializable, otherwise

Notes:

  • reverts: InvalidInitialization. registry must be non-zero, otherwise

  • reverts: NotAllowed.

function initialize(IDotnsProtocolRegistry registry) external initializer;

Parameters

NameTypeDescription
registryIDotnsProtocolRegistryProtocol-level address registry used to resolve sibling contracts.

setSubnodeOwner

Creates or reassigns a subnode and assigns its owner.

Callable only by the current owner of record.parentNode, otherwise

Note: reverts: NotAuthorised. The new owner address must be non-zero, otherwise

function setSubnodeOwner(SubnodeRecord calldata record)
    external
    override
    authorised(record.parentNode)
    returns (bytes32 subnode);

setOwner

Creates or resets a node record for a tokenised base registration.

Restricted to the registrar's controllers, otherwise @custom:reverts NotAuthorised. newOwner must be non-zero (otherwise @custom:reverts NotAllowed) and must match the ERC-721 owner reported by the registrar (otherwise

Notes:

  • reverts: NotAuthorised). The function is callable both on a fresh registration and on every reclaim from escrow: each call rewrites records[node].resolver to the protocol-registered default reverse resolver so a prior owner's resolver pointer (and the records keyed under it) cannot be inherited by the next holder. Stores owner = address(0) as a sentinel so reads delegate to IDotnsRegistrar.ownerOf and ERC-721 transfers remain authoritative. Emits

  • emits: NodeTransferred on success.

function setOwner(bytes32 node, address newOwner) external override onlyRegistrarController;

setResolver

Sets or clears the resolver for a node.

Callable only by the current node owner, otherwise @custom:reverts NotAuthorised. For tokenised nodes, authorisation falls back to ERC-721 owner / approved / operator-for-all via the registrar. The registry does not validate resolverAddr against any interface or code presence; off-chain consumers must verify resolver shape before trusting reads. Emits @custom:emits NewResolver on success.

function setResolver(bytes32 node, address newResolver) external override authorised(node);

Parameters

NameTypeDescription
nodebytes32
newResolveraddress

setSubnodeResolver

Sets the resolver for an existing subnode.

Callable only by the current owner of record.parentNode, otherwise

Note: reverts: NotAuthorised. The subnode owner can still update the resolver directly via setResolver. Both entry points emit the same NewResolver(subnode, ...) event, so the parent can silently override a subnode owner's chosen resolver: this is the parent-sovereign hierarchy applied to resolution. Off-chain consumers that surface trust signals to subnode owners should treat any resolver rotation as a re-attestation prompt. record.subLabel must be a single canonical DNS label (otherwise @custom:reverts InvalidLabel) and record.parentLabel must be a name path whose namehash matches record.parentNode (otherwise

function setSubnodeResolver(SubnodeResolverRecord calldata record)
    external
    override
    authorised(record.parentNode);

owner

Returns the owner of a node.

For tokenised nodes the stored owner is the zero sentinel; the implementation falls back to IDotnsRegistrar.ownerOf(uint256(node)).

function owner(bytes32 node) external view override returns (address);

resolver

Returns the resolver of a node.

function resolver(bytes32 node) external view override returns (address);

recordExists

Returns whether a node exists.

function recordExists(bytes32 node) external view override returns (bool);

isAuthorised

Returns whether account is authorised to manage node.

For subnodes, authority is the explicit stored owner. For tokenised nodes it is the ERC-721 owner, an address approved for the token, or an operator approved for all of the owner's tokens via the registrar. This is the canonical authorisation check the registry enforces on owner-gated entry points; sibling contracts may consult it so a single registrar-level approval delegates management across the protocol. Returns false for a node that does not exist.

function isAuthorised(
    bytes32 node,
    address account
)
    external
    view
    override
    returns (bool authorisedFlag);

Parameters

NameTypeDescription
nodebytes32Node identifier.
accountaddressAddress whose authority is being checked.

Returns

NameTypeDescription
authorisedFlagboolTrue when account may manage node.

_writeSubnodeToStore

Writes subnode registration to the owner's LabelStore.

Keys the entry by node (full namehash) rather than labelhash so a single store lookup yields the canonical full name without re-walking the parent chain.

function _writeSubnodeToStore(
    address storeOwner,
    bytes32 node,
    string memory fullName
)
    internal;

_parentNamehash

Computes the namehash of parentLabel rooted at the configured TLD.

Walks the label right-to-left in calldata using memory-safe assembly to avoid the cost of slicing into intermediate bytes and to keep gas linear in the label depth.

function _parentNamehash(string calldata parentLabel) internal pure returns (bytes32 node);

_authorised

Internal authorisation check for node ownership.

Reverts with NotAuthorised when msg.sender is not authorised for node.

function _authorised(bytes32 node) internal view;

_isAuthorised

Canonical authorisation rule for a node, parameterised by account.

Honours the sentinel-zero pattern: if the registry has no explicit owner, fall back to the registrar's ERC-721 owner / approved / operator-for-all chain. This is the single source of truth _authorised and isAuthorised both delegate to.

function _isAuthorised(bytes32 node, address account) internal view returns (bool);

_onlyRegistrarController

Internal check for registrar-authorised controller privileges.

The registry trusts every controller the registrar trusts. Routing controller authorisation through the registrar's controllers mapping keeps the trust list in one place and lets commit-reveal and PoP controllers coexist without registry reconfiguration on each addition.

function _onlyRegistrarController() internal view;

version

Returns implementation version.

function version() external pure virtual returns (string memory versionString);

Returns

NameTypeDescription
versionStringstringCurrent version string.

_authorizeUpgrade

Function that should revert when msg.sender is not authorized to upgrade the contract. Called by {upgradeToAndCall}. Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.

function _authorizeUpgrade(address) internal onlyOwner {}
function _authorizeUpgrade(address newImplementation) internal override onlyOwner;