跳到主要内容

存储数据

Gear 智能合约的持久化数据的存储方式与传统程序相同,不需要初始化外部存储。

// ...
// describe state structure
#[derive(TypeInfo, Decode, Encode, Clone)]
pub struct Wallet {
pub id: ActorId,
pub person: String,
}

// declare and initialize the state
static mut WALLETS: Vec<Wallet> = Vec::new();

如果用 Rust 或其他面向对象的语言编程,你应该对大多数类型都很熟悉。然而,在 Gear 上开发合约时,ActorId 类型是一个新内容。

信息

ActorId 是一个特殊的类型,代表一个 32 字节的数组,并定义了 Gear Protocol 中所有的 ID

State 函数

为了显示合约状态信息(类似于view函数),使用 state() 函数。它可以立即读取合约状态(例如,余额)。读取状态是一个免费函数,不需要消耗任何 gas。

要返回 State 使用:

#[no_mangle]
extern "C" fn state() {
msg::reply(unsafe { WALLETS.clone() }, 0).expect("Failed to share state");
}

默认情况下,state() 函数返合约的整体状态。

自定义程序读取状态

此外,你可以创建自己的程序来读取状态。这个包装器将允许你为客户端实现自定义函数,而不依赖于主程序。

这有很多优点,例如,即使程序改变了,也始终能够读取状态(只要输入或输出的类型没有改变)。或者你正在基于一个已经存在的程序创建服务,你需要一些自己的函数来从状态中获得你自己的数据块。

为此,我们需要创建一个独立的程序并在 metawasm 特征中描述必要的功能。例如:

// ...
use gmeta::metawasm;

#[metawasm]
pub trait Metawasm {
type State = Vec<Wallet>;

fn all_wallets(state: Self::State) -> Vec<Wallet> {
state
}

fn first_wallet(state: Self::State) -> Option<Wallet> {
state.first().cloned()
}

fn last_wallet(state: Self::State) -> Option<Wallet> {
state.last().cloned()
}
}

更多复杂的例子:

// ...
use gmeta::metawasm;

#[metawasm]
pub trait Metawasm {
type State = Vec<Wallet>;

fn wallet_by_id(id: Id, state: Self::State) -> Option<Wallet> {
state.into_iter().find(|w| w.id == id)
}

fn wallet_by_person(person: String, state: Self::State) -> Option<Wallet> {
state.into_iter().find(|w| w.person == person)
}
}

要构建 meta.wasm,需要在项目根目录下设置 build.rs 文件:

fn main() {
gear_wasm_builder::build_metawasm();
}

请看更多关于 metadata的内容。