Skip to main content

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

tip

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.

warning

...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 and serde::Deserialize are allowed.

Most of the Rust standard library types already implement these traits. Additionally, types you'll find in cosmwasm_std (like Addr, Decimal, Binary or Coin) 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.

tip

cw-storage-plus uses serde-json-wasm under the hood. This provides determinism in some corners - serde_json would not be suited for the blockchain world! On top of that, serde-json-wasm is just smaller.