StringUtils
Title: String Utilities Library
Provides string manipulation utilities for DotNS contracts.
Extends OpenZeppelin's Strings library with additional UTF-8 and conversion helpers.
Note: security-contact: admin@parity.io
Constants
LITE_SUFFIX_DIGITS
Number of digits in a lite-person PoP label's suffix.
The count the gateway emits, and an exact requirement here: the separator sits at a fixed offset from the end, so a one or three digit suffix is rejected. The gateway reads its own minimum, so widening it there does not widen this.
uint256 internal constant LITE_SUFFIX_DIGITS = 2
MAX_DNS_LABEL_OCTETS
Maximum number of octets in a single DNS label.
RFC 1035 caps each label at 63 octets. Enforced inside @custom:function _isDnsLabel so every public validator (@custom:function isSingleLabel, @custom:function isNamePath,
Note:
function: isLitePersonLabel) inherits the bound and oversized labels never
reach the registrar. A lite label bounds its stem rather than the whole string, so
it reaches MAX_DNS_LABEL_OCTETS + LITE_SUFFIX_DIGITS + 1 octets. Its stem is
bounded here but checked in @custom:function _isLitePersonLabel, which is stricter
on charset than a DNS label: letters only.
uint256 internal constant MAX_DNS_LABEL_OCTETS = 63
LABEL_SEPARATOR
ASCII full stop separating a lite label's stem from its digit suffix.
A lite label is the only label shape in DotNS that carries a separator;
Note: function: _isDnsLabel rejects it everywhere else.
bytes1 internal constant LABEL_SEPARATOR = 0x2e
Functions
strlen
Computes the character length of a UTF-8 encoded string.
Counts Unicode code points, not bytes. Handles multi-byte UTF-8 sequences:
- 1 byte: 0x00-0x7F (ASCII)
- 2 bytes: 0xC0-0xDF
- 3 bytes: 0xE0-0xEF
- 4 bytes: 0xF0-0xF7
- 5 bytes: 0xF8-0xFB (rare, outside Unicode standard)
- 6 bytes: 0xFC-0xFD (rare, outside Unicode standard)
function strlen(string memory value) internal pure returns (uint256 len);
Parameters
| Name | Type | Description |
|---|---|---|
value | string | The UTF-8 encoded string to measure. |
Returns
| Name | Type | Description |
|---|---|---|
len | uint256 | The number of Unicode characters in the string. |
isSingleLabel
Validates that s is a single canonical DNS label.
Lowercase ASCII letters, digits, and hyphen only; hyphen may not be the first or last
character; length must be in (0, MAX_DNS_LABEL_OCTETS]. No dots allowed; use
Note: function: isNamePath for dotted forms. Mirrors the label rules enforced at the registrar.
function isSingleLabel(string calldata value) internal pure returns (bool isValid);
Parameters
| Name | Type | Description |
|---|---|---|
value | string | Candidate label. |
Returns
| Name | Type | Description |
|---|---|---|
isValid | bool | True if value is a canonical DNS label. |
isSingleLabelMemory
Memory-location helper for @custom:function isSingleLabel, used where the candidate label is produced by an upstream string transformation (e.g. the output of
Note: function: stripDigits) so callers do not need a calldata round-trip.
function isSingleLabelMemory(string memory value) internal pure returns (bool isValid);
Parameters
| Name | Type | Description |
|---|---|---|
value | string | Candidate label held in memory. |
Returns
| Name | Type | Description |
|---|---|---|
isValid | bool | True if value is a canonical DNS label. |
isLitePersonLabel
Validates the lite-person PoP label format: <stem>.<digits>.
A lite-person label is a stem of lowercase ASCII letters, one
Notes:
-
constant: LABEL_SEPARATOR, then exactly
-
constant: LITE_SUFFIX_DIGITS digits (e.g.
joseph.42). Letters only, because the stem is the name a person chose, which is restricted to letters. How short a stem may be is policy rather than format, so it is left to the governance-reserved band in -
function: IPopRules.classifyName. It is the only label shape in DotNS permitted to carry a separator, which is what reserves the dotted space to the gateway. A digit suffix is not exclusive: an ordinary label may end in digits, but it is measured as written and so classifies by its full length. Cross-flow priority is arbitrated on the stem, not on the whole label: a lite label's stem is reserved as a base name through
-
function: IPopRules.reserveBaseNameForPop, so
joseph.42contends withjoseph. There is no flat spelling of a lite label for it to contend with.
function isLitePersonLabel(string calldata value) internal pure returns (bool isValid);
Parameters
| Name | Type | Description |
|---|---|---|
value | string | Candidate label. |
Returns
| Name | Type | Description |
|---|---|---|
isValid | bool | True if value is a stem of lowercase ASCII letters followed by a separator and exactly @custom:constant LITE_SUFFIX_DIGITS digits. |
isLitePersonLabelMemory
Memory-location helper for @custom:function isLitePersonLabel.
For callers holding the label in memory rather than calldata: the controller reads it back from a struct before deriving the node, and the lens reads it out of a store. Same predicate, different data location.
function isLitePersonLabelMemory(string memory value) internal pure returns (bool isValid);
Parameters
| Name | Type | Description |
|---|---|---|
value | string | Candidate label held in memory. |
Returns
| Name | Type | Description |
|---|---|---|
isValid | bool | True if value is a stem of lowercase ASCII letters followed by a separator and exactly @custom:constant LITE_SUFFIX_DIGITS digits. |
_isLitePersonLabel
function _isLitePersonLabel(bytes memory raw) private pure returns (bool isValid);
isPersonLabel
Validates that value is a name a person chose: lowercase ASCII letters only.
Matches the gateway's full-person label rule, which admits no digits and no hyphens, so a label outside this shape cannot have been issued. Stricter than @custom:function isSingleLabel, and it is the same rule
Note: function: isLitePersonLabel applies to a lite stem. How short a name may be is policy rather than format, so no floor is applied here.
function isPersonLabel(string calldata value) internal pure returns (bool isValid);
Parameters
| Name | Type | Description |
|---|---|---|
value | string | Candidate label. |
Returns
| Name | Type | Description |
|---|---|---|
isValid | bool | True if every octet of value is a lowercase ASCII letter. |
_isPersonLabel
function _isPersonLabel(
bytes memory raw,
uint256 start,
uint256 end
)
private
pure
returns (bool isValid);
splitLiteLabel
Splits a lite-person label <stem>.<digits> into its stem and digit suffix.
Splits at the first @custom:constant LABEL_SEPARATOR. A lite label carries exactly one separator, so the caller is expected to have run @custom:function isLitePersonLabelMemory first; a label with no separator returns the whole input as the stem and an empty suffix, which the caller's later label checks reject.
function splitLiteLabel(string memory value)
internal
pure
returns (string memory stem, string memory suffix);
Parameters
| Name | Type | Description |
|---|---|---|
value | string | Lite label held in memory, for example alice.01. |
Returns
| Name | Type | Description |
|---|---|---|
stem | string | The label before the separator, for example alice. |
suffix | string | The digit suffix after the separator, for example 01. |
isNamePath
Validates that s is a dot-separated path of canonical DNS labels.
Each segment between dots must satisfy @custom:function isSingleLabel. Empty
segments (leading, trailing, or consecutive dots) fail. Used when
callers submit multi-label paths (e.g. alice.dot) rather than
bare labels.
function isNamePath(string calldata value) internal pure returns (bool isValid);
Parameters
| Name | Type | Description |
|---|---|---|
value | string | Candidate name path. |
Returns
| Name | Type | Description |
|---|---|---|
isValid | bool | True if every dot-separated segment is a canonical DNS label. |
_isDnsLabel
function _isDnsLabel(
bytes memory label,
uint256 start,
uint256 end
)
private
pure
returns (bool isValid);
uintToString
Converts a uint256 to its decimal string representation.
Wraps OpenZeppelin's Strings.toString().
function uintToString(uint256 value) internal pure returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
value | uint256 | The unsigned integer to convert. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The decimal string representation. |
addressToHex
Converts an address to its checksummed hexadecimal string representation.
Wraps OpenZeppelin's Strings.toHexString(). Returns lowercase hex with "0x" prefix.
function addressToHex(address account) internal pure returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
account | address | The address to convert. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The hexadecimal string representation (42 characters including "0x"). |
bytes32ToString
Converts a bytes32 value to a string, treating it as a null-terminated ASCII string.
Reads bytes until the first null byte (0x00) or end of bytes32. Useful for converting short strings stored in bytes32 back to string type.
function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
_bytes32 | bytes32 | The bytes32 value containing a null-terminated ASCII string. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The extracted string (up to 32 characters). |