storage文档

说明

此文档将详细讲解substrate中的状态存储相关的操作

StorageMap

定义StorageMap

普通方法

pub struct StorageMap<
    Prefix,
    Hasher, // hash的方式自己选择, hash是用在key上而不是value
    Key, 
    Value, 
    QueryKind = OptionQuery,  // 默认是option 因为option当值为None时,提供自动删除的方法
    OnEmpty = GetDefault,
    MaxValues = GetDefault,  // 这个有什么意义????
>(core::marker::PhantomData<(Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues)>);

[pallet::storage]默认自动实现prefix,prefix包括模块prefix和storage的prefix。

impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
    crate::storage::generator::StorageMap<Key, Value>
    for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
where
    Prefix: StorageInstance,
    Hasher: crate::hash::StorageHasher,
    Key: FullCodec,
    Value: FullCodec,
    QueryKind: QueryKindTrait<Value, OnEmpty>,
    OnEmpty: Get<QueryKind::Query> + 'static,
    MaxValues: Get<Option<u32>>,
{
    type Query = QueryKind::Query;
    type Hasher = Hasher;
    fn module_prefix() -> &'static [u8] {
        Prefix::pallet_prefix().as_bytes()
    }
    fn storage_prefix() -> &'static [u8] {
        Prefix::STORAGE_PREFIX.as_bytes()
    }
    // fixme 这个方法有什么用???
    fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
        QueryKind::from_optional_value_to_query(v)
    }
    // fixme 这个方法有什么用???
    fn from_query_to_optional_value(v: Self::Query) -> Option<Value> {
        QueryKind::from_query_to_optional_value(v)
    }
}

获取某个key的hash值

pub fn hashed_key_for<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Vec<u8> {
        <Self as crate::storage::StorageMap<Key, Value>>::hashed_key_for(key)
    }

检查某个key是否存在值

/// Does the value (explicitly) exist in storage?
    pub fn contains_key<KeyArg: EncodeLike<Key>>(key: KeyArg) -> bool {
        <Self as crate::storage::StorageMap<Key, Value>>::contains_key(key)
    }

直接获取值,不存在就会返回默认值或者None

/// Load the value associated with the given key from the map.
    pub fn get<KeyArg: EncodeLike<Key>>(key: KeyArg) -> QueryKind::Query {
        <Self as crate::storage::StorageMap<Key, Value>>::get(key)
    }

获取值,不存在的话直接返回错误

pub fn try_get<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Result<Value, ()> {
        <Self as crate::storage::StorageMap<Key, Value>>::try_get(key)
    }

两个key之间互相交换值

pub fn swap<KeyArg1: EncodeLike<Key>, KeyArg2: EncodeLike<Key>>(key1: KeyArg1, key2: KeyArg2) {
        <Self as crate::storage::StorageMap<Key, Value>>::swap(key1, key2)
    }

删除或者设置key的value,如果value是None, 那么就删除数据

pub fn set<KeyArg: EncodeLike<Key>>(key: KeyArg, q: QueryKind::Query) {
        <Self as crate::storage::StorageMap<Key, Value>>::set(key, q)
    }

给某个key插入新的value

/// Store a value to be associated with the given key from the map.
/// fixme 好像不能用option做参数
    pub fn insert<KeyArg: EncodeLike<Key>, ValArg: EncodeLike<Value>>(key: KeyArg, val: ValArg) {
        <Self as crate::storage::StorageMap<Key, Value>>::insert(key, val)
    }

删除某个key

/// Remove the value under a key.
    pub fn remove<KeyArg: EncodeLike<Key>>(key: KeyArg) {
        <Self as crate::storage::StorageMap<Key, Value>>::remove(key)
    }

修改某个key下面的value

/// Mutate the value under a key.
    pub fn mutate<KeyArg: EncodeLike<Key>, R, F: FnOnce(&mut QueryKind::Query) -> R>(
        key: KeyArg,
        f: F,
    ) -> R {
        <Self as crate::storage::StorageMap<Key, Value>>::mutate(key, f)
    }

修改某个key下面的value, 返回ok才会修改成功,否则不修改

pub fn try_mutate<KeyArg, R, E, F>(key: KeyArg, f: F) -> Result<R, E>
    where
        KeyArg: EncodeLike<Key>,
        F: FnOnce(&mut QueryKind::Query) -> Result<R, E>,
    {
        <Self as crate::storage::StorageMap<Key, Value>>::try_mutate(key, f)
    }

修改某个key下面的value,如果value为None值, 那么删除

pub fn mutate_exists<KeyArg: EncodeLike<Key>, R, F: FnOnce(&mut Option<Value>) -> R>(
        key: KeyArg,
        f: F,
    ) -> R {
        <Self as crate::storage::StorageMap<Key, Value>>::mutate_exists(key, f)
    }

修改某个key下面的value,如果value为None值, 那么删除. 返回ok修改才成功

pub fn try_mutate_exists<KeyArg, R, E, F>(key: KeyArg, f: F) -> Result<R, E>
    where
        KeyArg: EncodeLike<Key>,
        F: FnOnce(&mut Option<Value>) -> Result<R, E>,
    {
        <Self as crate::storage::StorageMap<Key, Value>>::try_mutate_exists(key, f)
    }

把某个key的值拿出来,并且删除掉这个key

/// Take the value under a key.
    pub fn take<KeyArg: EncodeLike<Key>>(key: KeyArg) -> QueryKind::Query {
        <Self as crate::storage::StorageMap<Key, Value>>::take(key)
    }

给某个key的value追加元素

pub fn append<Item, EncodeLikeItem, EncodeLikeKey>(key: EncodeLikeKey, item: EncodeLikeItem)
    where
        EncodeLikeKey: EncodeLike<Key>,
        Item: Encode,
        EncodeLikeItem: EncodeLike<Item>,
        Value: StorageAppend<Item>,
    {
        <Self as crate::storage::StorageMap<Key, Value>>::append(key, item)
    }

给某个key的value追加元素,只有ok时候才会修改成功

pub fn try_append<KArg, Item, EncodeLikeItem>(key: KArg, item: EncodeLikeItem) -> Result<(), ()>
    where
        KArg: EncodeLike<Key> + Clone,
        Item: Encode,
        EncodeLikeItem: EncodeLike<Item>,
        Value: StorageTryAppend<Item>,
    {
        <Self as crate::storage::TryAppendMap<Key, Value, Item>>::try_append(key, item)
    }

获取某个key下面的value的总字节长度

pub fn decode_len<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Option<usize>
    where
        Value: StorageDecodeLength,
    {
        <Self as crate::storage::StorageMap<Key, Value>>::decode_len(key)
    }

改变某个Storage中key的hash值,当数据迁移时候需要重新解码编码,
因为编码需要耗费时间比较长,所以用key做参数。所以在数据hash算法的选择上一定要谨慎

pub fn migrate_key<OldHasher: crate::hash::StorageHasher, KeyArg: EncodeLike<Key>>(
        key: KeyArg,
    ) -> Option<Value> {
        <Self as crate::storage::StorageMap<Key, Value>>::migrate_key::<OldHasher, _>(key)
    }

列出某个Storage下所有value, 解析错误的话会跳过

pub fn iter_values() -> crate::storage::PrefixIterator<Value> {
        <Self as crate::storage::StoragePrefixedMap<Value>>::iter_values()
    }

当value的数据类型改变,需要在迁移的时候进行更改

pub fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(f: F) {
        <Self as crate::storage::StoragePrefixedMap<Value>>::translate_values(f)
    }

当value的数据类型改变,需要在迁移的时候进行更改, 这个可以获得对应的key,可操作空间比translate_values

pub fn translate<O: Decode, F: FnMut(Key, O) -> Option<Value>>(f: F) {
        <Self as crate::storage::IterableStorageMap<Key, Value>>::translate(f)
    }

迭代相关

/// Enumerate all elements in the map in no particular order.
    ///
    /// If you alter the map while doing this, you'll get undefined results.
    pub fn iter() -> crate::storage::PrefixIterator<(Key, Value)> {
        <Self as crate::storage::IterableStorageMap<Key, Value>>::iter()
    }

    /// Enumerate all elements in the map after a specified `starting_raw_key` in no
    /// particular order.
    ///
    /// If you alter the map while doing this, you'll get undefined results.
    pub fn iter_from(starting_raw_key: Vec<u8>) -> crate::storage::PrefixIterator<(Key, Value)> {
        <Self as crate::storage::IterableStorageMap<Key, Value>>::iter_from(starting_raw_key)
    }

    /// Enumerate all keys in the map in no particular order.
    ///
    /// If you alter the map while doing this, you'll get undefined results.
    pub fn iter_keys() -> crate::storage::KeyPrefixIterator<Key> {
        <Self as crate::storage::IterableStorageMap<Key, Value>>::iter_keys()
    }

    /// Enumerate all keys in the map after a specified `starting_raw_key` in no particular
    /// order.
    ///
    /// If you alter the map while doing this, you'll get undefined results.
    pub fn iter_keys_from(starting_raw_key: Vec<u8>) -> crate::storage::KeyPrefixIterator<Key> {
        <Self as crate::storage::IterableStorageMap<Key, Value>>::iter_keys_from(starting_raw_key)
    }

    /// Remove all elements from the map and iterate through them in no particular order.
    ///
    /// If you add elements to the map while doing this, you'll get undefined results.
    pub fn drain() -> crate::storage::PrefixIterator<(Key, Value)> {
        <Self as crate::storage::IterableStorageMap<Key, Value>>::drain()
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Laravel 学习交流 QQ 群:375462817 本文档前言Laravel 文档写的很好,只是新手看起来会有...
    Leonzai阅读 12,505评论 2 12
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,293评论 19 139
  • 一、MemCache简介 session MemCache是一个自由、源码开放、高性能、分布式的分布式内存对象缓存...
    李伟铭MIng阅读 9,256评论 2 13
  • Table of Contents WSGIwsgi服务器作用wsgirefhttp协议无状态,短连接,长连接co...
    四月天_da7e阅读 3,283评论 0 0
  • 首先分析数据库模型! 用户表: id, 用户名, 密码, 邮箱, 激活标志, 权限标识(是否管理员) 地址表 :...
    上帝大人阅读 7,414评论 0 2