Basics
Containers
`cw-storage-plus`` provides several storage containers that can be used to store data on the blockchain. The fundamental ones are:
An Item
is a simple container that stores a single value. The other two are a
little more involved - they are collections capable of storing multiple values, and provide several
methods to interact with them.
Keys and prefixes
One task of a storage library like cw-storage-plus
is to manage the namespace of keys provided by
the blockchain.
When constructing a container, you must provide a key of type &'static str
(or use
new_dyn
(opens in a new tab)).
This usually means you'll be providing a string literal or some constant.
In the case of an Item
, the provided string is the exact key (a standard UTF-8
string) under which the value will be saved. In the case of collections, the provided string is a
prefix (sometimes called namespace
in the code); the collection will use this prefix to generate
keys (by appending to it) for the individual values it stores.
As a contract dev, it is your responsibility to ensure that the keys you provide are unique and do not conflict with keys used by other parts of the contract.
Over time, we've learned that using long keys hurts storage performance. If you gotta go fast, a good approach might be to only provide single-character ASCII prefixes for your containers, like "a", "b", "c", etc.
Generally speaking, we tried to make it so that as long as you use a unique prefix for each container, you shouldn't have to worry about key conflicts.
TODO: Research the key collisions in the warning below more! Then we can provide better advice.
...yet there's a small but. A Map
's prefix is length-prefixed. An Item
is saved without any
sort of length-prefixing of the key. It is, in theory, possible for an Item
's key to conflict
with one of the keys generated by a Map
or Deque
. In practice, this is unlikely unless you use
very long prefixes or start your Item
's key with the null byte. Probably don't do that!
Values
In cw-storage-plus
, every value is saved using JSON serialization. For that to be possible, only
types that implement serde::Serialize
(opens in a new tab)
and serde::Deserialize
(opens in a new tab) are allowed.
Most of the Rust standard library types already implement these traits. Additionally, types you'll
find in cosmwasm_std
(like
Addr
(opens in a new tab),
Decimal
(opens in a new tab),
Binary
(opens in a new tab) or
Coin
(opens in a new tab)) often do as well.
If you're writing a custom type and wish to send it across call or put it in storage, you'll have to derive these traits.
cw-storage-plus uses serde-json-wasm (opens in a new tab) under the
hood. This provides determinism in some corners - serde_json (opens in a new tab)
would not be suited for the blockchain world! On top of that, serde-json-wasm
is just smaller.