Header
header

cover text
Header

Gear 合约入门介绍

智能合约特性和开发范例

Hangbiao

⚙️ Validator Manager

  • 什么是 Gear

    • Rust 与 WebAssembly
    • Hello World
  • Actor 模型

    • 消息类型
    • 内部状态
    • 消息处理
    • 元数据
  • 开发范例

Header

什么是 Gear

基于 Substrate 的智能合约平台 (PoS, L1)

Smart Contract Engine for Polkadot
  • Actor Model

  • Persistent Memory

  • WebAssembly

Vara Standalone Network
...
    {
      "prefix": 137,
      "network": "vara",
      "displayName": "Vara Network",
      "symbols": ["VARA"],
      "decimals": [12],
      "standardAccount": "*25519",
      "website": "https://vara-network.io/"
    },
...

Coming soon! (source)

Kusama & Polkadot Parachain

Stay tuned!

Header

Rust 与 WebAssembly

WebAssembly: 高效、可移植的二进制指令格式 (W3C标准)

  • Rust / C / C++ / Zig / AssemblyScript ...

Rust: 多范式通用编程语言 (Safety, Speed, Concurrency)

Header

Hello World

cargo new ...

$ cargo new --lib hello-gear && cd hello-gear

cargo add ...

$ cargo add --git https://github.com/gear-tech/gear.git --build gear-wasm-builder
$ cargo add --git https://github.com/gear-tech/gear.git --dev gtest
$ cargo add --git https://github.com/gear-tech/gear.git gstd
Header

./rust-toolchain

[toolchain]
channel = "nightly"
components = [ "rustfmt", "clippy" ]
targets = [ "wasm32-unknown-unknown" ]
profile = "minimal"

./src/lib.rs

#![no_std]

#[no_mangle]
extern "C" fn handle() {
  let _ = gstd::msg::load_bytes(); // read input message and do nothing 
  gstd::msg::reply_bytes(gstd::String::from("Hello world!"), 0);
}
Header

./build.rs

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

cargo build --release

  • ./target/wasm32-unknown-unknown/release/hello_gear.opt.wasm
    • 合约代码 (Code)
    • 提交上链 -> CodeId -> 部署 (+salt) -> ProgramId
  • ./target/wasm32-unknown-unknown/release/hello_gear.meta.wasm
    • 合约 Metadata
    • @gear-js/api
Header

解码消息 Payload

0x => ⚙️ => 0x48656c6c6f20776f726c6421

使用 @gear-js/gear-meta

$ gear-meta decode --type String "0x48656c6c6f20776f726c6421" \
    --meta ./target/wasm32-unknown-unknown/release/hello_gear.meta.wasm
Hello world!

使用 @gear-js/api

import { CreateType } from "@gear-js/api";

let result = CreateType.create(
  "String",
  "0x48656c6c6f20776f726c6421",
  "./target/wasm32-unknown-unknown/release/hello_gear.meta.wasm",
);
console.log(JSON.stringify(result.toJSON()));
Header

使用 wabt 查看 WASM 模块导入导出的符号

$ wasm2wat target/wasm32-unknown-unknown/release/hello_gear.opt.wasm | grep 'port '
  (import "env" "memory" (memory (;0;) 17))
  (import "env" "alloc" (func (;0;) (type 0)))
  (import "env" "free" (func (;1;) (type 1)))
  (import "env" "gr_error" (func (;2;) (type 2)))
  (import "env" "gr_size" (func (;3;) (type 1)))
  (import "env" "gr_read" (func (;4;) (type 3)))
  (export "handle" (func 21))
  (export "__gear_stack_end" (global 0))
$ wasm2wat target/wasm32-unknown-unknown/release/hello_gear.meta.wasm | grep 'port '
  (import "env" "memory" (memory (;0;) 17))
Header

开发者常用工具/库/参考范例

合约 (Program) 相关

交互

工具

参考范例

Header

Actor 模型

一切皆是 Actor

Header

账户体系

gstd::ActorId 256-bit Unique Identifier

Gear allows users and programs to interact with other users and programs via messages. Source and target program as well as user are represented by 256-bit identifier ActorId struct.

  • 📝 合约(Program)地址 (aka ProgramId), 例如
    0x512905fcf25de5e576c5c9302b75efd68372e9d835945089f046f6170a0ef91a
  • 🐱 用户地址 (即 SS58 公钥), 例如:
    0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
    • 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY //Alice
    • ss58.org
Header

Actor 遵循的规则

在 Actor 处理收到的消息时,它可以:

  • 向另一个 Actor 发送消息
  • 创建新的 Actor
  • 改变其内部状态

Note: Gear Protocol 在传统的 Actor 模型上额外保证了合约(Program)间消息的顺序

Header

消息类型

scale-encoding

#[derive(Debug, Encode, Decode, TypeInfo)]
#[codec(crate = gstd::codec)]
#[scale_info(crate = gstd::scale_info)]
pub enum InitConfig { ... }
pub enum FTAction { ... }
pub enum FTEvent { ... }
pub enum State { ... }
pub enum StateReply { ... }
Header

内部状态

#[derive(Debug, Default)]
struct FungibleToken {
    /// Name of the token.
    name: String,
    /// Symbol of the token.
    symbol: String,
    /// Total supply of the token.
    total_supply: u128,
    /// Map to hold balances of token holders.
    balances: BTreeMap<ActorId, u128>,
    /// Map to hold allowance information of token holders.
    allowances: BTreeMap<ActorId, BTreeMap<ActorId, u128>>,
    /// Token's decimals.
    pub decimals: u8,
}

static mut FUNGIBLE_TOKEN: Option<FungibleToken> = None;
Header

消息处理

初始化

#[no_mangle]
extern "C" fn init() {
    let config: InitConfig = msg::load().expect("Unable to decode InitConfig");
    let ft = FungibleToken {
        name: config.name,
        symbol: config.symbol,
        decimals: config.decimals,
        ..Default::default()
    };
    unsafe { FUNGIBLE_TOKEN = Some(ft) };
}
Header

常规消息

#[no_mangle]
extern "C" fn handle() {
  ...
}

状态查询

#[no_mangle]
extern "C" fn meta_state() -> *mut [i32; 2] {
  ...
}
Header

元数据

gstd::metadata! {
    title: "FungibleToken",
    init:
        input: InitConfig,
    handle:
        input: FTAction,
        output: FTEvent,
    state:
        input: State,
        output: StateReply,
}
Header

开发范例

Decentralized Finance (DeFi)
Decentralized Autonomous Orgs (DAOs)
Non-fungible Tokens (NFTs)
Staking
Wallets
Tools&Explorers
Web3/eCommerce
Oracles

👉 https://wiki.gear-tech.io/docs/examples/prerequisites

近期将上线 Vara Network 主网

类似面向对象编程里面的 "一切皆对象"

关于 Actor 具体怎么翻译,不重要,因为这个概念本身是由其行为定义的,只要弄清楚 Actor 本身的行为,也就明白了这个概念

在弄清楚什么是 Actor 之前,先来看看 "一切皆是 Actor" 在 Gear 当中的体现

下面会逐个说明在 Gear 合约中的 [消息类型],[内部状态], [消息处理], [元数据] 在代码层面分别如何体现