DotnsContentResolver

Git Source

Inherits: Initializable, UUPSUpgradeable, OwnableUpgradeable, ERC165Upgradeable, IDotnsContentResolver

Title: dotNS Content Resolver

Implements IDotnsContentResolver interface with content hash, text records, and operator approvals.

Writes are gated on the registry's authorisation for the node (owner or registrar-level approval) or on a resolver-local operator the owner has approved, rather than on a privileged writer address. Content records are user-managed metadata, so write authority follows the node owner across transfers and honours the same delegates the registry recognises. Each record is stamped with the node's record version from the registry (@custom:function IDotnsRegistry.recordVersion), and a read returns empty unless the node still resolves and the stamp is current, so clearing a name never has to list its text keys.

Note: security-contact: admin@parity.io

State Variables

contenthashes

Stores all content hash mappings

mapping(bytes32 node => bytes contentHash) private contenthashes

textRecords

Stores all text records

mapping(bytes32 node => mapping(string key => string value)) private textRecords

operators

Store all approval mapping

mapping(address owner => mapping(address operator => bool approved)) private operators

protocolRegistry

Protocol-level address registry for all dotNS contracts.

IDotnsProtocolRegistry public protocolRegistry

__gap

Reserved storage space. It sits before contenthashVersions and textVersions, so it must never shrink: add new state after the last variable instead.

uint256[50] private __gap

contenthashVersions

Node => registry record version its content hash was written under.

Zero matches the record version every node starts at, so a content hash stamped zero reads as set until its node is first cleared. The same holds for textVersions.

mapping(bytes32 node => uint64 version) private contenthashVersions

textVersions

Node => text key => registry record version the value was written under.

mapping(bytes32 node => mapping(string key => uint64 version)) private textVersions

Functions

constructor

Note: oz-upgrades-unsafe-allow: constructor

constructor() ;

initialize

Initialises the content resolver.

Runs once through the UUPS proxy; a repeat call reverts with

Note: reverts: InvalidInitialization. Emits @custom:emits OwnershipTransferred when msg.sender is recorded as the initial owner and @custom:emits Initialized once setup completes.

function initialize(
    address initialOwner,
    IDotnsProtocolRegistry registry
)
    external
    initializer;

Parameters

NameTypeDescription
initialOwneraddressAddress that owns the contract once initialised.
registryIDotnsProtocolRegistryProtocol-level address registry used to resolve sibling contracts.

setContenthash

Sets the content hash for a node.

The caller must own the node in the dotNS registry or be an approved operator, otherwise @custom:reverts NotAuthorised. Content hashes are opaque bytes (e.g. an IPFS CID); the resolver stores them as-is and never interprets the payload. An empty hash deletes the record: its storage is zeroed and the storage deposit released to the signer of the transaction. Emits @custom:emits ContentHashUpdated on every successful write.

function setContenthash(bytes32 node, bytes calldata hash) external override;

Parameters

NameTypeDescription
nodebytes32The node whose content hash is being set.
hashbytesOpaque content hash bytes.

contenthash

Returns the content hash associated with a node.

A record reads as unset once the node is cleared (@custom:function IDotnsRegistry.clearRecords) or stops resolving because a name above it was cleared, even though the bytes written before stay in storage.

function contenthash(bytes32 node) external view override returns (bytes memory hash);

Parameters

NameTypeDescription
nodebytes32The node to query.

Returns

NameTypeDescription
hashbytesThe stored content hash bytes, or empty if unset.

setText

Sets a text record for a node.

The caller must own the node in the dotNS registry or be an approved operator, otherwise @custom:reverts NotAuthorised. Text records are arbitrary key/value strings (e.g. avatar, url, description). An empty value deletes the record: its storage is zeroed and the storage deposit released to the signer of the transaction. That also works for a key a clear has already hidden, which still holds storage until it is deleted. Emits @custom:emits TextUpdated and @custom:emits TextChanged on every successful write, a delete included.

function setText(bytes32 node, string calldata key, string calldata value) external override;

Parameters

NameTypeDescription
nodebytes32The node whose text record is being set.
keystringText record key (e.g., "ipfs", "avatar").
valuestringText record value.

text

Returns a text record for a node.

A record reads as unset once the node is cleared (@custom:function IDotnsRegistry.clearRecords) or stops resolving because a name above it was cleared, even though the bytes written before stay in storage.

function text(
    bytes32 node,
    string calldata key
)
    external
    view
    override
    returns (string memory value);

Parameters

NameTypeDescription
nodebytes32The node to query.
keystringText record key.

Returns

NameTypeDescription
valuestringStored text value, or empty string if unset.

setApprovalForAll

Enable or disable approval for a third party ("operator") to manage all of msg.sender's nodes.

Emits @custom:emits ApprovalForAll whenever the approval flag is written, including idempotent writes that do not change the stored value.

function setApprovalForAll(address operator, bool approved) external override;

Parameters

NameTypeDescription
operatoraddressAddress to authorise or revoke.
approvedboolTrue to approve, false to revoke.

isApprovedForAll

Query if an address is an approved operator for another address.

function isApprovedForAll(
    address owner,
    address operator
)
    external
    view
    override
    returns (bool);

Parameters

NameTypeDescription
owneraddressThe owner of the nodes.
operatoraddressThe address acting on behalf of the owner.

Returns

NameTypeDescription
<none>boolTrue if operator is approved, false otherwise.

_requireNodeOwnerOrOperator

Ensures the caller may write records for node.

Authority is granted to the node owner, to a resolver-local operator the owner has approved for all of their records, or to any address the registry deems authorised for the node. Delegating through the registry means a single registrar-level approval (ERC-721 owner / approved / operator-for-all) also confers record-write authority, while the resolver-local operator mapping remains a narrower record-only delegation that grants no power over ownership or transfers. The cheap owner and local-operator checks run before the cross-contract registry call.

function _requireNodeOwnerOrOperator(bytes32 node)
    internal
    view
    returns (uint64 currentVersion);

Parameters

NameTypeDescription
nodebytes32Node identifier.

Returns

NameTypeDescription
currentVersionuint64Record version of node, which the caller stamps the write with.

_isCurrent

Returns whether a record stamped stamp is readable for node.

Every getter goes through here. A getter that skipped it would serve records the node has cleared, so a new record type must read through it too.

function _isCurrent(bytes32 node, uint64 stamp) internal view returns (bool current);

Parameters

NameTypeDescription
nodebytes32Node identifier.
stampuint64Record version the record was written under.

Returns

NameTypeDescription
currentboolTrue when node resolves and stamp is its current record version.

_forwardRegistry

Returns the forward registry, resolved lazily so a rewire needs no upgrade here.

function _forwardRegistry() internal view returns (IDotnsRegistry registry);

Returns

NameTypeDescription
registryIDotnsRegistryThe forward registry.

version

Returns the release this network declares it runs, read live from the protocol registry so every dotNS contract reports one synchronised value.

Mirror of IDotnsProtocolRegistry.protocolVersion, kept under the historical version() selector for ABI compatibility. It reports the network's declaration, not this contract's build; per-contract identity is the codehash declared on the registry.

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

Returns

NameTypeDescription
versionStringstringDeclared release as bare semver, empty when never declared.

supportsInterface

function supportsInterface(bytes4 interfaceId) public view override returns (bool);

_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;