DotnsRegistry
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.
registrymust be non-zero, otherwise -
reverts: NotAllowed.
function initialize(IDotnsProtocolRegistry registry) external initializer;
Parameters
| Name | Type | Description |
|---|---|---|
registry | IDotnsProtocolRegistry | Protocol-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].resolverto 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. Storesowner = address(0)as a sentinel so reads delegate toIDotnsRegistrar.ownerOfand 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
| Name | Type | Description |
|---|---|---|
node | bytes32 | |
newResolver | address |
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
| Name | Type | Description |
|---|---|---|
node | bytes32 | Node identifier. |
account | address | Address whose authority is being checked. |
Returns
| Name | Type | Description |
|---|---|---|
authorisedFlag | bool | True 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
| Name | Type | Description |
|---|---|---|
versionString | string | Current 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;