IDotnsRegistrarController
Inherits: IDotnsController
Title: Dotns Registrar Controller
Interface for registering top-level labels using a commit reveal scheme.
Defines allocation only; forward resolution, reverse lookup, pricing mechanics, PoP validation, and store writing are handled by external contracts. Users commit a hash of registration parameters and, after a minimum delay, reveal the same parameters to register. Implementations write the successfully registered name into the user's Store to create an immutable on-chain record that doubles as a quick lookup for all names registered.
Note: security-contact: admin@parity.io
Functions
available
Returns whether a label is available for registration.
Validates the canonical DNS-label shape (otherwise @custom:reverts InvalidLabel) and rejects labels below the minimum-length policy with
Note: reverts: LabelTooShort before checking ERC721 availability on the registrar.
function available(string calldata label) external view returns (bool isAvailable);
makeCommitment
Computes the commitment hash for a registration.
Uses abi.encode so the variable-width label is length-prefixed and the boundary
between label and the fixed-width owner, secret, reserved, maxPrice, and
pricingVersion fields is unambiguous, binding the commitment to the exact tuple. The
price ceiling and cost-model version are part of that tuple, so neither can be altered
between commit and reveal.
function makeCommitment(Registration calldata registration)
external
pure
returns (bytes32 commitment);
commit
Submits a commitment for a future registration.
Idempotent over expiry: re-committing an unexpired hash reverts with
Note:
reverts: UnexpiredCommitmentExists (front-running guard); a hash whose stored
timestamp has passed maxCommitmentAge overwrites the slot so storage cannot be
permanently griefed. The expiry boundary is inclusive on the commit side
(committedAt + maxCommitmentAge <= block.timestamp overwrites) and exclusive on the
reveal side (register rejects at the same instant with @custom:reverts
CommitmentTooOld), so the slot is overwritable from exactly the timestamp at which
reveal begins rejecting it. Stamps the cost model's current version on the commitment, so
the reveal binds to the version live now and rejects a pricingVersion bound to an earlier
one with @custom:reverts PricingVersionMismatch. Emits @custom:emits NameCommitted on
success.
function commit(bytes32 commitment) external;
register
Registers a name after the commitment delay.
Validates the label shape (otherwise @custom:reverts InvalidLabel), rejects labels
below the minimum length policy (@custom:reverts LabelTooShort), and ERC721 availability
(otherwise @custom:reverts NameNotAvailable), then consumes the prior commitment, which
fails with @custom:reverts CommitmentNotFound when no commitment exists for the supplied
registration, @custom:reverts CommitmentTooNew before minCommitmentAge, and
Notes:
-
reverts: CommitmentTooOld past
maxCommitmentAge, and finally resolves the configured escrow address from the protocol registry (otherwise -
reverts: EscrowNotConfigured). Splits on direct vs cross-payer at
msg.sender == registration.owner. The direct path runspriceWithCheck(personhood
- reservation gate) and routes the charge to a refundable escrow deposit owned by
registration.owner. The cross-payer path skips the personhood revert inpriceWithCheckbut applies it directly via @custom:reverts OwnerStatusInsufficient when the owner's recorded tier does not meet the label's required tier, and still rejects governance-reserved labels with @custom:reverts GovernanceReserved and live cross-user stem reservations with @custom:reverts NameReserved. The cross-payer charge is the owner-side registration price; the path applies no separate transfer friction. The charge routes to the escrow protocol fee pot while seeding a zero-amount deposit slot so the release lifecycle stays reachable. The reveal prices the name at the committedpricingVersion, so a model change between commit and reveal leaves the amount unchanged, and rejects a total charge above the committed ceiling with @custom:reverts PriceExceedsMax before checking payment. The caller must supply at least the charge (otherwise @custom:reverts InsufficientValue); any overpayment is pushed back tomsg.senderinline and, on failure, credited to the escrow's pull-payment ledger so contract receivers cannot block registration. Emits @custom:emits OverpaymentRefunded on the inline branch, the escrow's own @custom:emits OverpaymentRefunded on the pull fallback, and @custom:emits NameRegistered on success.
function register(Registration calldata registration) external payable;
registerReserved
Registers a name after the commitment delay.
Whitelisted issuance path used to seed reserved labels at zero base cost: skips the PoP price check and the escrow deposit, but reuses the same commit-reveal pipeline so the same anti-front-running guarantees apply. Restricted to whitelisted callers and the owner (otherwise @custom:reverts NotWhiteListedOrOwner). Validates the label shape (otherwise @custom:reverts InvalidLabel) and ERC721 availability (otherwise
Notes:
-
reverts: NameNotAvailable), then consumes the prior commitment, which fails with
-
reverts: CommitmentNotFound, @custom:reverts CommitmentTooNew, or
-
reverts: CommitmentTooOld under the same conditions as @custom:function register. Emits
-
emits: NameRegistered on success.
function registerReserved(Registration calldata registration) external;
isWhiteListed
Checks if the given address is whitelisted to call registerReserved.
function isWhiteListed(address who) external view returns (bool isWhiteListed);
whiteListAddress
Adds or removes an address from the whitelist for registerReserved.
Callable by the owner or an account holding DotnsConstants.WHITELIST_OPERATOR_ROLE;
any other caller reverts with @custom:reverts IDotnsRoleManager.NotRoleOrOwner. Emits
Note: emits: WhiteListed on success.
function whiteListAddress(address who, bool whiteListStatus) external;
Events
NameCommitted
Emitted when a commitment is submitted.
event NameCommitted(bytes32 indexed commitment);
NameRegistered
Emitted when a name is successfully registered.
event NameRegistered(
string indexed label,
bytes32 indexed labelhash,
address indexed owner,
uint256 baseCost,
address store
);
Parameters
| Name | Type | Description |
|---|---|---|
label | string | |
labelhash | bytes32 | |
owner | address | |
baseCost | uint256 | The price returned by the oracle for this registration. |
store | address | The Store instance used to persist an immutable registration record. |
WhiteListed
Emitted when an address is added to or removed from the whitelist.
event WhiteListed(address indexed who, bool indexed whiteListStatus);
OverpaymentRefunded
Emitted when overpayment is refunded to the payer at registration entry.
event OverpaymentRefunded(address indexed payer, uint256 amount);
Errors
NotWhiteListedOrOwner
Thrown when the caller is not whitelisted or the owner.
error NotWhiteListedOrOwner(address caller);
UnexpiredCommitmentExists
Thrown when an unexpired commitment already exists.
error UnexpiredCommitmentExists(bytes32 commitment);
CommitmentNotFound
Thrown when revealing a commitment that does not exist.
error CommitmentNotFound(bytes32 commitment);
CommitmentTooNew
Thrown when a commitment is revealed before the minimum age.
error CommitmentTooNew(bytes32 commitment, uint256 minTime, uint256 currentTime);
CommitmentTooOld
Thrown when a commitment has expired.
error CommitmentTooOld(bytes32 commitment, uint256 maxTime, uint256 currentTime);
NameNotAvailable
Thrown when attempting to register an unavailable name.
error NameNotAvailable(string label);
LabelTooShort
Thrown when a label is below the minimum-length policy.
Distinct from @custom:reverts NameNotAvailable so off-chain consumers can tell a too-short label apart from a name that is already minted.
error LabelTooShort(string label);
Parameters
| Name | Type | Description |
|---|---|---|
label | string | Caller-supplied label that failed the minimum-length policy. |
InvalidLabel
Thrown when a label is not a canonical lowercase ASCII DNS label.
error InvalidLabel();
InsufficientValue
Thrown when supplied payment is insufficient.
error InsufficientValue();
PriceExceedsMax
Thrown when the total charge exceeds the ceiling the caller committed to.
error PriceExceedsMax(string label, uint256 charged, uint256 maxPrice);
Parameters
| Name | Type | Description |
|---|---|---|
label | string | Label whose charge exceeded the ceiling. |
charged | uint256 | Total charge computed at reveal. |
maxPrice | uint256 | Ceiling the caller committed to. |
EscrowNotConfigured
Thrown when escrow is not configured in the protocol registry.
error EscrowNotConfigured();
MinCommitmentAgeZero
Thrown when min commitment age is zero, which would allow same-block commit-reveal and defeat the front-running guard.
error MinCommitmentAgeZero();
MaxCommitmentAgeTooLow
Thrown when max commitment age is invalid (must be > minCommitmentAge).
error MaxCommitmentAgeTooLow();
MaxCommitmentAgeTooHigh
Thrown when max commitment age is invalid (exceeds implementation limit).
error MaxCommitmentAgeTooHigh();
Structs
Registration
Parameters used to generate and reveal a commitment.
All fields must match exactly between commitment and reveal.
struct Registration {
string label;
address owner;
bytes32 secret;
bool reserved;
uint256 maxPrice;
uint256 pricingVersion;
}
Properties
| Name | Type | Description |
|---|---|---|
label | string | Label being registered (e.g. "alice"). |
owner | address | Beneficiary the registered name is minted to. |
secret | bytes32 | Caller-chosen entropy that hides the registration intent in the commit hash; revealed verbatim at registration time. |
reserved | bool | True when the registration flows through the whitelisted reserved pipeline (registerReserved); false for the standard public flow (register). |
maxPrice | uint256 | Ceiling in wei the caller accepts for this registration; a reveal charged above it reverts, closing the gap between the price at commit and the price at reveal. |
pricingVersion | uint256 | Cost-model version the caller committed to; the reveal prices the name at this version, so a model change between commit and reveal leaves the amount unchanged. It must equal the version current when commit ran, which that call stamps on the commitment; a reveal whose pricingVersion differs reverts, so the caller cannot bind an earlier, cheaper version. |