KVStore.sol
The KVStore contract implements a simple on‑chain key–value storage for strings. Each account maintains its own dictionary of string keys and string values.
Key Features and Components#
Per‑Account Key–Value Storage#
- The storage layout is a nested mapping:
mapping(address => mapping(string => string)). Each user’s key‑value pairs are isolated; only the caller can set values under their own address.
String Length Constraint#
- The contract defines a constant
MAX_STRING_LENGTH(1000 bytes). Both the key and value insetandsetBulkmust not exceed this length. This protects against excessive gas consumption, since storing data on chain is costly.
Bulk Operations#
- To improve efficiency,
setBulklets a user store multiple key‑value pairs in a single transaction. It requires the number of keys to match the number of values and limits the count to less thanBULK_MAX_COUNT(20 entries). This prevents excessively large transactions and helps control gas usage.
Event Logging#
- Every successful write emits a
DataSavedevent containing the sender’s address, the key and the new value.
Roles#
| Role | Capabilities |
|---|---|
| User | Any address can read values with get and write to their own key‑value store using set or setBulk. There is no owner or administrator; the contract is entirely permissionless. |
Workflow/Functions#
get#
- View function that returns the value associated with
_keyin_account’s store. Because mappings return default values for unset keys, the return value is an empty string if the key has not been set.
set#
- Writes or updates a key–value pair in the caller’s store.
- Validates that the byte length of
_keyand_valuedoes not exceedMAX_STRING_LENGTH. This guards against storing arbitrarily large strings and the associated gas costs. - Emits a
DataSavedevent with the sender, key and value.
setBulk#
- Allows multiple key–value pairs to be set in a single transaction. It checks that
_keys.length == _values.lengthto ensure pairs are aligned. - Requires
_keys.lengthto be less thanBULK_MAX_COUNT(20 entries). This prevents overly large loops and helps cap the gas consumed per transaction. - Iterates over each key–value pair and internally calls
set(_keys[i], _values[i]). Each call performs the same length checks. - Emits a
DataSavedevent per key.
Security and Trust#
- Permissionless design – There is no owner. Any address can call
set,setBulkorget. Users can only write to their own storage because the mapping is keyed bymsg.sender. - Gas cost safeguards – To avoid storing excessively large strings—each 32‑byte storage word costs 20 000 gas—the contract enforces a maximum length on keys and values and a maximum number of entries per bulk operation.
- Event transparency – The
DataSavedevent logs all writes. Events are stored outside contract storage and are cheaper to emit; they can be monitored by external applications to track changes. - Data persistence – Once written, data persists unless overwritten. Solidity mappings have no length or mechanism to iterate keys, so the contract does not provide a way to list or delete keys. Users should therefore manage keys carefully and avoid storing sensitive information on chain.
Overall, KVStore provides a straightforward on‑chain key–value store with built‑in safeguards for gas consumption and a transparent event system for monitoring writes.