三、入门Substrate之常用存储数据类型和它们相应的操作API

三、入门Substrate之常用存储数据类型和它们相应的操作API

Substrate作为一个通用的区块链开发框架,提供了丰富的数据类型用于在链上存储数据。

运行时存储允许您将数据存储在区块链中,这些数据在块之间持久存在,并且可以从运行时逻辑中访问。存储应该是区块链运行时开发人员最关心的问题之一。精心设计的存储系统减少了网络中节点的负载,最终降低了区块链参与者的间接成本。换句话说,区块链运行时存储的基本原则是尽量减少其使用。

  • Storage Value 用于存储任何单值类型,例如u8、u16
  • Storage Map 用于存储键值哈希映射,例如余额到帐户的映射。
  • Storage Double Map 用作具有两个键的存储映射的实现,以提供有效删除具有公共第一个键的所有条目的能力。
  • Storage N Map - 用于存储具有任意数量键的哈希映射,可作为构建三重存储映射、四重存储映射等的基础。

1.StorageValue

1).整数类型

例如:存一个u32

//第一个参数为_固定,ValueQuery参数可填可不填,不填get获取就是Option包裹的u32,填上就直接返回u32
//pub(super) v2版 区块链存储始终在运行时之外公开 可见
#[pallet::storage]
#[pallet::getter(fn something)]
pub(super) type TestStorageValue<T> = StorageValue<_, u32,ValueQuery>;

//存入值
TestStorageValue::<T>::put(3);
// something() 和 TestStorageValue::<T>::get()的操作结果一样
//获取值
something() 
TestStorageValue::<T>::get()

//数值运算存在溢出风险应该使用更加安全的api
let temp_value = TestStorageValue::<T>::get().checked_add(2).ok_or(Error::<T>::StorageOverflow)?;

KittiesCount::<T>::put(kitty_id + 1u32.into());

2).boolean

存入获取用法同上

3).Vec

//引入
use frame_support::inherent::Vec;

#[pallet::storage]
#[pallet::getter(fn get_vec_value)]
pub type TestVecValue<T> = StorageValue<_, Vec<u8>,ValueQuery>;

//和原生Rust操作一样
let mut test_vec = Vec::new();
			test_vec.push(2);
			test_vec.push(3);
			test_vec.push(3);
TestVecValue::<T>::put(test_vec);

4).string &str

不支持,将字符串转成vec再存入值

//相互转换
let str_vec = b"test".to_vec();
let vec_str = String::from_utf8(str_vec).unwrap();

5).struct

//引入
use frame_support::codec::{Encode, Decode};

//定义
#[derive(Encode, Decode, Clone, PartialEq)]
pub struct Person{
    pub number: u32,
    pub name: Vec<u8>,
}

//定义StorageValue
#[pallet::storage]
#[pallet::getter(fn get_struct_value)]
pub type TestStructValue<T> = StorageValue<_, Person>;

//存入值
let person = Person{
				number:1,
				name:name,
};
TestStructValue::<T>::put(person);

2.StorageMap

键值对

//定义
#[pallet::storage]
#[pallet::getter(fn get_struct_map)]
pub type StructMap<T:Config> = StorageMap<_,Blake2_128Concat,T::AccountId,Person>;

// 插入一个元素
StructMap::<T>::insert(key, value);

// 通过key获取value
StructMap::<T>::get(key);

// 删除某个key对应的元素
StructMap::<T>::remove(key);

//是否包含key,返回bool
StructMap::<T>::contains_key(key); 

// 覆盖或者修改某个key对应的元素
StructMap::<T>::insert(key, new_value);
StructMap::<T>::mutate(key, |old_value| old_value+1);

3.DoubleMap

暂未使用到,后续补充

4.配置一个常量

#[pallet::config]
pub trait Config: frame_system::Config {
        type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
  		  //配置常量
        #[pallet::constant]
        type MaxCardSize: Get<u32>;
    }

//获取它的值
T::MaxCardSize::get()


//在runtime的lib.rs中配置它
parameter_types! {
  //设置值
	pub const MaxCardSize: u32 = 1024 * 1024;
}
impl pallet_coming_id::Config for Runtime {
	type Event = Event;
  //添加上
	type MaxCardSize = MaxCardSize;
}

5.创世配置

//先定义一个存储它的StorageValue
#[pallet::storage]
#[pallet::getter(fn high_admin_key)]
pub(super) type HighKey<T: Config> = StorageValue<_, T::AccountId, ValueQuery>;

//创世配置
#[pallet::genesis_config]
    pub struct GenesisConfig<T: Config> {
        pub high_admin_key: T::AccountId,
    }
//要实现Default,不然报错
	#[cfg(feature = "std")]
    impl<T: Config> Default for GenesisConfig<T> {
        fn default() -> Self {
            Self {
                high_admin_key: Default::default(),
            }
        }
    }
#[pallet::genesis_build]
impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
        fn build(&self) {
            <HighKey<T>>::put(&self.high_admin_key);
        }
    }


//注意Runtime中的lib.rs里面要改一下
//加一个 Config<T>
TemplateModule: pallet_template::{Pallet, Call,Config<T>, Storage, Event<T>},


//最后在Node中的chain_spec.rs配置一下 注意template_module和TemplateModule关系,TemplateModuleConfig也是一个注意点,默认就叫这个名字后面加上Config
template_module: TemplateModuleConfig {
            // Assign network admin rights.
            high_admin_key: root_key.clone(),
},

总结:以上就是最常用到底数据类型以及常见操作,因为笔者也在学习过程中,后面也会补充在项目中常常使用到的操作,如果想广泛学习方法建议打开文档自己学习。

在学习完,pallet开发中基本配置和常使用的存储数据类型之后,在下一篇文章中,会尝试开发一个pallet-erc20实例

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值