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

__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.

function initialize(address user_) external override initializer;

Parameters

NameTypeDescription
user_addressThe user this store is bound to forever.

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 implementation version.

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

Returns

NameTypeDescription
versionStringstringCurrent version string.

_onlyOwner

Internal owner check deferred from the onlyOwner modifier.

function _onlyOwner() internal view;