SubnodeUtils

Git Source

Title: dotNS Subnode Utilities Library

General-purpose helpers for registering names that live as subnodes of another name, rather than as tokenised second-level registrations.

A subname has no token: its ownership lives in the registry record, not in the registrar's ERC-721 ledger. So it is registered through @custom:function IDotnsRegistry.setSubnodeOwner beneath a parent prepared by @custom:function ensureParent, rather than through the tokenised mint triad of @custom:contract RegistrationUtils.

Note: security-contact: admin@parity.io

Functions

subnodeOf

Derives the subnode subLabel.parentLabel.tld.

The single source of truth for how a two-level name maps to a node: walk parentLabel under tldNode, then subLabel under that. Consumers that need the node without writing it (readers, validators) call this so they agree with the write path.

function subnodeOf(
    bytes32 tldNode,
    string memory parentLabel,
    string memory subLabel
)
    internal
    pure
    returns (bytes32 subnode);

Parameters

NameTypeDescription
tldNodebytes32The TLD node.
parentLabelstringSecond-level parent label, e.g. 01.
subLabelstringSubname label, e.g. alice.

Returns

NameTypeDescription
subnodebytes32Namehash of subLabel under parentLabel.tld.

deviceSubnodeOf

Derives the subnode for a device name <stem>.<suffix>, splitting it on the separator first.

The single place a device name is turned into a node, shared by the write path and every reader of a device name so the issuer and its readers agree on where a device name lives. Callers gate on @custom:function StringUtils.isDeviceLabelMemory beforehand, so the label is known to carry the separator this splits on.

function deviceSubnodeOf(
    bytes32 tldNode,
    string memory deviceLabel
)
    internal
    pure
    returns (bytes32 subnode);

Parameters

NameTypeDescription
tldNodebytes32The TLD node.
deviceLabelstringDevice name, e.g. alice.01.

Returns

NameTypeDescription
subnodebytes32Namehash of the stem beneath its numeric container beneath the TLD.

ensureParent

Makes the calling contract the owner of the second-level name parentNode, minting it if no name is registered there yet, so the caller can register subnames beneath it.

When no name exists at parentNode, it is minted through the registrar with the calling contract as owner and an empty label, so no LabelStore is written for it. The calling contract must therefore be a registrar controller, otherwise the registrar

The parent is owned by the calling contract's address. A caller that migrates to a new address, rather than upgrading in place, strands every parent it minted and can no longer register subnames beneath them.

Notes:

  • reverts: NotController. When a name already exists there it must be owned by the caller, otherwise @custom:reverts NotAuthorised, so a name someone else holds is never treated as the caller's parent. The caller then records each subname through

  • function: IDotnsRegistry.setSubnodeOwner, which requires that parent authority.

function ensureParent(
    IDotnsRegistrar registrar,
    IDotnsRegistry registry,
    bytes32 parentNode
)
    internal;

Parameters

NameTypeDescription
registrarIDotnsRegistrarThe base registrar.
registryIDotnsRegistryThe forward registry.
parentNodebytes32Node of a single label registered directly under the TLD.