substrate入門-常用宏和常用存儲類型


substrate常用宏

substrate為了便於模塊式的開發,定義了需要的宏;對於開發者來說,只需要按照相應的模板,編寫具體的業務邏輯即可,加快了開發速度,下面羅列了常用的一些宏定義

// 定義具體的一個功能模塊
#[frame_support::pallet]
pub mod pallet {}

// 定義相關存儲類型 
#[pallet::storage]
#[pallet::getter(fn something)]
pub type Something<T> = StorageValue<_, u32>;

// 定義觸發的時間類型
#[pallet::event]
#[pallet::metadata(T::AccountId = "AccountId")]
#[pallet::generate_deposit(pub (super) fn deposit_event)]
pub enum Event<T: Config> {}

// 定義錯誤類型
#[pallet::error]
pub enum Error<T> {}

// 出塊前后的回調
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}

// 定義具體邏輯處理方法
#[pallet::call]
impl<T: Config> Pallet<T> {}

具體的使用方法,我們可以查看相關的例子,剛開始的時候可能有點懵,沒辦法要使用這個框架,都必須適應它的規則,這個沒啥難度的,花費時間去熟悉即可,具體的一個實例可以參考視頻

substrate常用存儲類型

  • 在代碼 frame_support庫中定義,為什么會有這些類型呢, 多數應用都需要存儲數據,Substrate底層使用的是RocketDb key-value數據庫,在整個基礎上進行了封裝,為了便於存儲數據需要我們需要這些api,下面列出了常用具體的類型和常用的一些方法。
  • 在使用過程中我們需要注意的是,盡量避免無用,耗時的操作(查找,遍歷耗時的操作),防止影響節點出塊。
  • 盡量避免存儲大數據在鏈上
  • 一般先驗證數據,在寫入
  • 創造限制邊界

StorageValue

StorageValue: 單值的類型,主要存儲單個值。

// 在模塊中的定義一個存儲,存儲類型為u32 
#[pallet::storage]
#[pallet::getter(fn something)]                   // 使用宏生成一個獲取該值的一個方法 something
pub type Something<T> = StorageValue<_, u32>;     // 定義一個存儲類型


// 存儲一個number值
Something::<T>::put(number);
// 讀取該值 
Something::<T>::get();
// 修改該值
Something::<T>::mutate(|v|v+1);
// 清楚該值 
Something::<T>::kill(); 
// 獲取值之后刪除
Something::<T>::take();

給類型設置默認值:

// 定義了一個獲取默認值的方法 
#[pallet::type_value]
pub fn my_default_value<T: Config>() -> u32 { 1337u32 }

// 作為一個默認值,把方法作為值傳入
#[pallet::storage]
#[pallet::getter(fn something)]
pub type Something<T:Config> = StorageValue<_, u32,ValueQuery,my_default_value<T>>;

// 讀取該值 
Something::<T>::get(); 

tips:

  • 除了使用以上格式調用之外呢,也還可以使用 <Something<T>>::get() 這樣格式調用
  • 其它的類型的調用方法也都大概類似,詳細的方法可以查看其api

url:

StorageMap

StorageMap: HashMap類型,存儲鍵值對。

// 定義存儲單元 ,存儲憑證
#[pallet::storage]
#[pallet::getter(fn proofs)]                // 定義了一個 proofs 函數
pub type Proofs<T: Config> = StorageMap<
    _,
    Blake2_128Concat,                       // 采用的hash算法
    Vec<u8>,                                // Map的Key,存儲的hash值
    (T::AccountId, T::BlockNumber)          // Map的value,定義的元組(賬號id,區塊高度)
>;


// 插入value
Proofs::<T>::insert(&user, entry);
// 獲取value
let entry = Proofs::<T>::get(account);
// Take
let entry = Proofs::<T>::take(&user);
// 是否包含該值
Proofs::<T>::contains_key(&user)

Hash算法

  • Blake2 128 Concat
  • TwoX 64 Concat
  • Identity

url:

StorageDoubleMap

StorageDoubleMap : 雙鍵值key Map類型

// 定義存儲,使用了Blake2_128Concat 算法定義了雙鍵(u32,AccountId)map,值為 u32
#[pallet::storage]
#[pallet::getter(fn SomeDoubleMap)]
pub type SomeDoubleMap<T: Config> = StorageDoubleMap<_, Blake2_128Concat, u32, Blake2_128Concat, T::AccountId, u32, ValueQuery>;

// 是否包含key
SomeDoubleMap::<T>::contains_key(key1, key2);
// 插入值 
SomeDoubleMap::<T>::insert(key1, key2, value);
// 獲取值
SomeDoubleMap::<T>::get(key1, key2);
// 刪除值
SomeDoubleMap::<T>::remove(key1,key2);

url:

StorageNMap

StorageNMap : 多鍵映射類型

// 定義多鍵值類型 ,key定義的是一個元組,value 是u32類型的 
#[pallet::storage]
#[pallet::getter(fn some_nmap)]
pub type SomeNMap<T: Config> = StorageNMap<
    _,
    (NMapKey<Blake2_128Concat, u32>, NMapKey<Blake2_128Concat, u32>, NMapKey<Blake2_128Concat, u32>),
    u32>;

// 是否存在
SomeNMap::<T>::contains_key(key1,key2,key3));
//插入
SomeNMap::<T>::insert((key1,key2,key3),100);
// 獲取
SomeNMap::<T>::get((key1,key2,key3))
// 刪除
SomeNMap::<T>::remove((key1,key2,key3))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM