DotnsContentResolver
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
| Name | Type | Description |
|---|---|---|
initialOwner | address | Address that owns the contract once initialised. |
registry | IDotnsProtocolRegistry | Protocol-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
| Name | Type | Description |
|---|---|---|
node | bytes32 | The node whose content hash is being set. |
hash | bytes | Opaque 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
| Name | Type | Description |
|---|---|---|
node | bytes32 | The node to query. |
Returns
| Name | Type | Description |
|---|---|---|
hash | bytes | The 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
| Name | Type | Description |
|---|---|---|
node | bytes32 | The node whose text record is being set. |
key | string | Text record key (e.g., "ipfs", "avatar"). |
value | string | Text 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
| Name | Type | Description |
|---|---|---|
node | bytes32 | The node to query. |
key | string | Text record key. |
Returns
| Name | Type | Description |
|---|---|---|
value | string | Stored 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
| Name | Type | Description |
|---|---|---|
operator | address | Address to authorise or revoke. |
approved | bool | True 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
| Name | Type | Description |
|---|---|---|
owner | address | The owner of the nodes. |
operator | address | The address acting on behalf of the owner. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True 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
| Name | Type | Description |
|---|---|---|
node | bytes32 | Node identifier. |
Returns
| Name | Type | Description |
|---|---|---|
currentVersion | uint64 | Record 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
| Name | Type | Description |
|---|---|---|
node | bytes32 | Node identifier. |
stamp | uint64 | Record version the record was written under. |
Returns
| Name | Type | Description |
|---|---|---|
current | bool | True 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
| Name | Type | Description |
|---|---|---|
registry | IDotnsRegistry | The 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
| Name | Type | Description |
|---|---|---|
versionString | string | Declared 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;