pallet进阶(9)-offchain index

链下索引,提供的是在链上操作链下存储的方式。

概述

注意区分链下存储和链下索引:
链下存储:所有的使用都是在链下进行的(准确的说是在ocw中进行的)
链下索引:链上操作链下存储的方式

案例

本示例的具体功能就是提供一个调度函数,在该调度函数中通过offchain_index设置链下存储,然后在ocw中将该链下存储的值打印出来。
pallet的lib.rs代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use scale_info::prelude::vec::Vec;

use sp_runtime::offchain::storage::StorageValueRef;

#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);

#[pallet::config]
pub trait Config: frame_system::Config {}

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn offchain_worker(_block_number: T::BlockNumber) {
if let Ok(some_number) = Self::get_local_storage() {
log::info!(target:"offchain-index-demo", "1. Offchain-index, some_number ======================== {:?}", some_number);
} else {
log::info!(target:"offchain-index-demo", "2. Offchain-index, no number in storage ==================== ");
}
}
}

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(0)]
pub fn set_local_storage(
origin: OriginFor<T>,
some_number: u32,
) -> DispatchResultWithPostInfo {
ensure_signed(origin)?;

Self::set_local_storage_with_offchain_index(some_number);
Ok(().into())
}
}

impl<T: Config> Pallet<T> {
fn derived_key() -> Vec<u8> {
b"offchain-index-demo::value".encode()
}

// 重点1:看这里,这里是通过offchain_index将值设置到链下存储,请注意key的值
fn set_local_storage_with_offchain_index(some_number: u32) {
let key = Self::derived_key();
sp_io::offchain_index::set(&key, some_number.encode().as_slice());
log::info!(target:"offchain-index-demo", "set some_number ======================== {:?}", some_number);
}

// 重点2:看这里,这里是从对应的链下存储读取,请注意key的值
fn get_local_storage() -> Result<u32, &'static str> {
let key = Self::derived_key();
let some_number_storage = StorageValueRef::persistent(&key);

if let Ok(Some(number)) = some_number_storage.get::<u32>() {
Ok(number)
} else {
Err("No number in storage.")
}
}
}
}

运行

启动节点时,需要加上--enable-offchain-indexing=true才能开启索引功能:

1
./target/debug/node-template --dev --enable-offchain-indexing=true

总结

本文编辑完毕

  • Copyrights © 2017-2023 Jason
  • Visitors: | Views:

谢谢打赏~

微信