UserStore
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
| Name | Type | Description |
|---|---|---|
user_ | address | The user this store is bound to forever. |
protocolRegistry_ | address | The 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
| Name | Type | Description |
|---|---|---|
protocolRegistry_ | address | The 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
| Name | Type | Description |
|---|---|---|
key | bytes32 | The key to write. |
value | bytes | The 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
| Name | Type | Description |
|---|---|---|
owner_ | address | The 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
| Name | Type | Description |
|---|---|---|
key | bytes32 | The key to read. |
Returns
| Name | Type | Description |
|---|---|---|
value | bytes | The 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
| Name | Type | Description |
|---|---|---|
key | bytes32 | The key to check. |
Returns
| Name | Type | Description |
|---|---|---|
present | bool | True 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
| Name | Type | Description |
|---|---|---|
key | bytes32 | The key to read. |
Returns
| Name | Type | Description |
|---|---|---|
count | uint256 | Length 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
| Name | Type | Description |
|---|---|---|
key | bytes32 | The key to read. |
index | uint256 | Zero-based index into the history list. |
Returns
| Name | Type | Description |
|---|---|---|
entry | Entry | The (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
| Name | Type | Description |
|---|---|---|
key | bytes32 | The key to read. |
offset | uint256 | Start index. |
limit | uint256 | Maximum entries to return. |
Returns
| Name | Type | Description |
|---|---|---|
entries | Entry[] | Slice of history entries. |
getKeyCount
Returns the number of distinct keys ever written.
function getKeyCount() external view override returns (uint256 count);
Returns
| Name | Type | Description |
|---|---|---|
count | uint256 | Length 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
| Name | Type | Description |
|---|---|---|
index | uint256 | Zero-based index into the key list. |
Returns
| Name | Type | Description |
|---|---|---|
key | bytes32 | The 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
| Name | Type | Description |
|---|---|---|
offset | uint256 | Start index. |
limit | uint256 | Maximum entries to return. |
Returns
| Name | Type | Description |
|---|---|---|
keys | bytes32[] | 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
| Name | Type | Description |
|---|---|---|
versionString | string | Declared 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;