UserStore

Git Source

Inherits: Initializable, IUserStore

Title: UserStore

Permanent per-user generic key/value store with per-key history.

One instance per user, deployed as a BeaconProxy by StoreFactory.claimUserStore. Bound to its claimer forever: _owner is set once at initialize and only that address may write. History is append-only; every setValue that supersedes a non-empty prior value records the supersession with block.timestamp.

Cost isolation: each user's writes bill their own contract, keeping shared resolvers from being polluted by one user's blob usage.

Storage collision: the BeaconProxy stores the beacon address at EIP-1967 slot keccak256("eip1967.proxy.beacon") - 1, which is non-sequential and cannot collide with this contract's sequential storage slots.

Note: security-contact: admin@parity.io

State Variables

_owner

Permanent user this store belongs to. Set in initialize.

address private _owner

_current

key => current value bytes.

mapping(bytes32 key => bytes value) private _current

_history

key => insertion-order list of prior non-empty values and their supersession timestamps.

mapping(bytes32 key => Entry[] entries) private _history

_keyList

Insertion-order list of all keys ever written. Append-only (never pruned).

bytes32[] private _keyList

_keyIndex

key => 1-indexed position in _keyList (zero means "never written").

mapping(bytes32 key => uint256 indexPlusOne) private _keyIndex

_protocolRegistry

Protocol registry, the one address a contract may hold directly; read for network-level facts such as the declared release.

address private _protocolRegistry

__gap

Reserved storage space to allow for layout changes in future beacon upgrades.

uint256[50] private __gap

Functions

onlyOwner

Restricts writes to the bound owner.

modifier onlyOwner() ;

constructor

Note: oz-upgrades-unsafe-allow: constructor

constructor() ;

initialize

Initialises the store, binding it permanently to user_.

Callable exactly once via Initializable. user_ must be non-zero, otherwise

Note: reverts: InvalidUser. protocolRegistry_ must be non-zero, otherwise

function initialize(address user_, address protocolRegistry_) external override initializer;

Parameters

NameTypeDescription
user_addressThe user this store is bound to forever.
protocolRegistry_addressThe protocol registry, held per the one-address rule so the store can report network-level facts such as the declared release.

protocolRegistry

Returns the protocol registry this store reads network-level facts from.

function protocolRegistry() external view override returns (address protocolRegistry_);

Returns

NameTypeDescription
protocolRegistry_addressThe registry address.

setValue

Sets the current value for key.

Callable only by the bound owner; any other caller @custom:reverts NotOwner. key must be non-zero, otherwise @custom:reverts InvalidKey. If a non-empty prior value existed it is pushed into the per-key history list with block.timestamp; empty prior values produce no history entry. Emits

Note: emits: ValueSet on every successful write.

function setValue(bytes32 key, bytes calldata value) external override onlyOwner;

Parameters

NameTypeDescription
keybytes32The key to write.
valuebytesThe new current value (may be empty).

owner

Returns the permanent user this store is bound to.

Set once at initialize and never mutated; used as the binding-mismatch oracle and immutable thereafter.

function owner() external view override returns (address owner_);

Returns

NameTypeDescription
owner_addressThe bound user address.

getValue

Returns the current value under key, or empty bytes if unset.

function getValue(bytes32 key) external view override returns (bytes memory value);

Parameters

NameTypeDescription
keybytes32The key to read.

Returns

NameTypeDescription
valuebytesThe current value.

hasValue

Returns true iff the current value under key has non-zero length.

function hasValue(bytes32 key) external view override returns (bool present);

Parameters

NameTypeDescription
keybytes32The key to check.

Returns

NameTypeDescription
presentboolTrue iff getValue(key).length != 0.

getHistoryCount

Returns the number of prior (historical) values recorded for key.

function getHistoryCount(bytes32 key) external view override returns (uint256 count);

Parameters

NameTypeDescription
keybytes32The key to read.

Returns

NameTypeDescription
countuint256Length of the history list.

getHistoryAt

Returns the historical entry at index for key.

function getHistoryAt(
    bytes32 key,
    uint256 index
)
    external
    view
    override
    returns (Entry memory entry);

Parameters

NameTypeDescription
keybytes32The key to read.
indexuint256Zero-based index into the history list.

Returns

NameTypeDescription
entryEntryThe (value, timestamp) pair.

getHistory

Paginated read over the per-key history list.

offset >= getHistoryCount(key) returns an empty array. Length is min(limit, getHistoryCount(key) - offset).

function getHistory(
    bytes32 key,
    uint256 offset,
    uint256 limit
)
    external
    view
    override
    returns (Entry[] memory entries);

Parameters

NameTypeDescription
keybytes32The key to read.
offsetuint256Start index.
limituint256Maximum entries to return.

Returns

NameTypeDescription
entriesEntry[]Slice of history entries.

getKeyCount

Returns the number of distinct keys ever written.

function getKeyCount() external view override returns (uint256 count);

Returns

NameTypeDescription
countuint256Length of the key-insertion list.

getKeyAt

Returns the key at the given insertion-order index.

function getKeyAt(uint256 index) external view override returns (bytes32 key);

Parameters

NameTypeDescription
indexuint256Zero-based index into the key list.

Returns

NameTypeDescription
keybytes32The key at index.

getKeys

Paginated read over the insertion-order key list.

offset >= getKeyCount() returns an empty array. Length is min(limit, getKeyCount() - offset).

function getKeys(
    uint256 offset,
    uint256 limit
)
    external
    view
    override
    returns (bytes32[] memory keys);

Parameters

NameTypeDescription
offsetuint256Start index.
limituint256Maximum entries to return.

Returns

NameTypeDescription
keysbytes32[]Slice of keys.

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. A store instance initialised before the registry pointer existed (a beacon upgrade on a live network reaches those) holds no registry to mirror, so it answers with the same "never declared" empty string instead of reverting.

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

Returns

NameTypeDescription
versionStringstringDeclared release as bare semver, empty when never declared or when this instance predates the registry pointer.

_onlyOwner

Internal owner check deferred from the onlyOwner modifier.

function _onlyOwner() internal view;