The one that you should use is the first one. If you take a look at the pallet_prelude
crate, you can see that the StorageMap
used across most of the tutorials is being 'imported' from the storage::types
crate.
pub use crate::{
dispatch::{DispatchError, DispatchResult, DispatchResultWithPostInfo, Parameter},
ensure,
inherent::{InherentData, InherentIdentifier, ProvideInherent},
storage,
storage::{
bounded_vec::BoundedVec,
types::{
CountedStorageMap, Key as NMapKey, OptionQuery, StorageDoubleMap, StorageMap,
HERE --> StorageNMap, StorageValue, ValueQuery,
},
},
traits::{
ConstU32, EnsureOrigin, Get, GetDefault, GetStorageVersion, Hooks, IsType,
PalletInfoAccess, StorageInfoTrait,
},
weights::{DispatchClass, Pays, Weight},
Blake2_128, Blake2_128Concat, Blake2_256, CloneNoBound, DebugNoBound, EqNoBound, Identity,
PartialEqNoBound, RuntimeDebug, RuntimeDebugNoBound, Twox128, Twox256, Twox64Concat,
};
So basically, when you call frame_support::pallet_prelude::StorageMap
you are calling the one inside the storage::types
crate.
As for the question 'why are there two StorageMaps?' I think the second one is used in old versions of FRAME, where you would use decl_storage
to create your structures. It has to exist because although substrate is being updated constantly, it is backward compatible with old implementations of it. But I'm not 100% sure thats the reason.
Taking a look at the storage::StorageMap
:
/// A strongly-typed map in storage.
///
/// Details on implementation can be found at [`generator::StorageMap`].
pub trait StorageMap<K: FullEncode, V: FullCodec> {
...
and then the generator::StorageMap
:
/// Generator for `StorageMap` used by `decl_storage`.
/// ...
pub trait StorageMap<K: FullEncode, V: FullCodec> {
The docs of the implementation state that the generator is used by the decl_storage
function.