Crate gstd

source ·
Expand description

Standard library for use in Gear programs.

This library should be used as a standard library when writing Gear programs. Compared to gcore crate, this library provides higher-level primitives that allow you to develop more complex dApps. Choose this library if you are ready to spend more gas but receive refined code.

gstd crate provides many advanced tools for a developer, such as asynchronous programming primitives, arbitrary types encoding/decoding, providing metadata about input/output types, convenient instruments for creating programs from programs, etc.


Decode input payload using a custom type and provide metadata for the front application:


use gstd::{metadata, msg, prelude::*};

#[derive(Decode, Encode, TypeInfo)]
#[codec(crate = gstd::codec)]
#[scale_info(crate = gstd::scale_info)]
struct Payload {
    question: String,
    answer: u8,

metadata! {
    title: "App",
        input: Payload,
        output: u8,

extern "C" fn handle() {
    let payload: Payload = msg::load().expect("Unable to decode payload");
    if payload.question == "life-universe-everything" {
        msg::reply(payload.answer, 0).expect("Unable to reply");

Asynchronous program example.

It sends empty messages to three addresses and waits for at least two replies (“approvals”) during initialization. When invoked, it handles only PING messages and sends empty messages to the three addresses, and waits for just one approval. If approval is obtained, the program replies with PONG.

use futures::future;
use gstd::{msg, prelude::*, ActorId};

static mut APPROVERS: [ActorId; 3] = [ActorId::zero(); 3];

#[derive(Debug, Decode, TypeInfo)]
#[codec(crate = gstd::codec)]
#[scale_info(crate = gstd::scale_info)]
pub struct Input {
    pub approvers: [ActorId; 3],

gstd::metadata! {
    title: "Async demo",
        input: Input,

async fn init() {
    let payload: Input = msg::load().expect("Failed to decode input");
    unsafe { APPROVERS = payload.approvers };

    let mut requests: Vec<_> = unsafe { APPROVERS }
        .map(|addr| msg::send_bytes_for_reply(*addr, b"", 0))
        .collect::<Result<_, _>>()

    let mut threshold = 0;
    while !requests.is_empty() {
        let (.., remaining) = future::select_all(requests).await;
        threshold += 1;
        if threshold >= 2 {
        requests = remaining;

async fn main() {
    let message = msg::load_bytes().expect("Failed to load payload bytes");
    if message != b"PING" {

    let requests: Vec<_> = unsafe { APPROVERS }
        .map(|addr| msg::send_bytes_for_reply(*addr, b"", 0))
        .collect::<Result<_, _>>()

    _ = future::select_all(requests).await;
    msg::reply(b"PONG", 0).expect("Unable to reply");



  • Type definitions and helpers for error handling.
  • Utility functions related to the current execution context or program execution flow.
  • Extensions for additional features.
  • Data access synchronization objects.
  • Messaging API for Gear programs.
  • The gstd default prelude. Re-imports default std modules and traits. std can be safely replaced to gstd in the Rust programs.
  • Functions and helpers for creating programs from programs.
  • Utility functions.


  • Unwrap Result<T, E> to T if it is Ok(T) or panic with the provided message if the result is Err(E).
  • Add a debug message to the log.
  • Create an FFI function that returns some data from the program as a fat pointer to the Wasm memory.
  • Provide information about input and output types as the metadata.



Attribute Macros

  • Mark async function to be the program initialization method.
  • Mark the main async function to be the program entry point.