Module store

Source
Expand description

Collections and types used when interacting with storage.

These collections are more scalable versions of std::collections when used as contract state because it allows values to be lazily loaded and stored based on what is actually interacted with.

Fundamentally, a contract’s storage is a key/value store where both keys and values are just Vec<u8>. If you want to store some structured data, for example, Vec<Account>, one way to achieve that would be to serialize the Vec to bytes and store that. This has a drawback in that accessing or modifying a single element would require reading the whole Vec from the storage.

That’s where store module helps. Its collections are backed by a key value store. For example, a store::Vector is stored as several key-value pairs, where indices are the keys. So, accessing a single element would only load this specific element.

To help you understand how cost-effective near collections are in terms of gas usage compared to native ones, take a look at this investigation: Near benchmarking github. The results of the investigation can be found here: Results. If your collection has up to 100 entries, it’s acceptable to use the native collection, as it might be simpler since you don’t have to manage prefixes as we do with near collections. However, if your collection has 1,000 or more entries, it’s better to use a near collection. The investigation mentioned above shows that running the contains method on a native std::collections::HashSet<i32> consumes 41% more gas compared to a near crate::store::IterableSet<i32>.

It’s also a bad practice to have a native collection properties as a top level properties of your contract. The contract will load all the properties before the contract method invocation. That means that all your native collections will be fully loaded into memory even if they are not used in the method you invoke.

It can be expensive to load all values into memory, and because of this, serde Serialize and Deserialize traits are intentionally not implemented. If you want to return all values from a storage collection from a function, consider using pagination with the collection iterators.

All of the collections implement BorshSerialize and BorshDeserialize to be able to store the metadata of the collections to be able to access all values. Because only metadata is serialized, these structures should not be used as a borsh return value from a function.

The collections are as follows:

Sequences:

  • Vector: Analogous to Vec but not contiguous and persisted to storage.

Maps:

Sets:

Basic Types:

  • Lazy<T>: Lazily loaded type that can be used in place of a type T. Will only be loaded when interacted with and will persist on Drop.

  • LazyOption<T>: Lazily loaded, optional type that can be used in place of a type Option<T>. Will only be loaded when interacted with and will persist on Drop.

  • More information about collections can be found in NEAR documentation
  • Benchmarking results of the NEAR-SDK store collections vs native collections can be found in github

Re-exports§

pub use vec::Vector;
pub use self::lookup_map::LookupMap;
pub use self::iterable_map::IterableMap;
pub use self::iterable_set::IterableSet;
pub use self::unordered_map::UnorderedMap;Deprecated
pub use self::unordered_set::UnorderedSet;Deprecated
pub use self::tree_map::TreeMap;

Modules§

iterable_map
iterable_set
key
Storage key hash function types and trait to override map hash functions.
lookup_map
tree_map
unordered_map
unordered_set
vec
A growable array type with values persisted to storage and lazily loaded.

Structs§

Lazy
An persistent lazily loaded value, that stores a value in the storage.
LazyOption
An persistent lazily loaded option, that stores a value in the storage when Some(value) is set, and not when None is set. LazyOption also Derefs into Option so we get all its APIs for free.
LookupSet
A non-iterable implementation of a set that stores its content directly on the storage trie.