当前位置:网站首页>Novice must see! How rust beginners write gear smart contracts (1)

Novice must see! How rust beginners write gear smart contracts (1)

2022-06-12 23:23:00 GearFans

about Gear Pre knowledge of contract , You can learn about this article first :Gear Contract disclosure .

This article will mainly explain how to use Rust stay Gear Create a simple decentralized application on the blockchain network .

Let's take a voting application as an example , To study Gear Infrastructure for smart contracts , And learn how to use the program Actor Model architecture , Process the message , And interact with States .

This article aims to demonstrate that Gear How easy and convenient it is to create applications on the platform .

Let's start with Rust Start

Rust It is a language with multiple programming paradigms focusing on security and performance . Its construction takes into account speed and efficiency , Provides zero cost abstraction and functional features . For many developers , It solves other underlying languages ( Such as c and c++) Frequently asked questions about .

About Gear Why use Rust, Please read this article : Why? Gear To use Rust?

Besides ,Rust There is also a significant advantage :rust The code can be compiled as wasm.

that , Let's start installing... On your computer Rust Well .

First , Open your favorite terminal and run the installer :

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Let's install the toolchain to compile the code :

rustup toolchain add nightly
rustup target add wasm32-unknown-unknown --toolchain nightly
cargo install --git https://github.com/gear-tech/gear wasm-proc

Everything is all set. , It's time to start our first program !

Create a Rust Program

Let us in cargo Create a voting application project with the help of the command :

cargo new voting-app --lib

Look at the project structure :

voting-app/
├── Cargo.toml
└── src
└── lib.rs

Cargo.toml yes Rust List of items in , It contains the metadata required to compile the project and some necessary dependent Libraries :

[package]
name = "voting-app"
version = "0.1.0"
authors = ["Gear Technologies"]
edition = "2018"
license = "GPL-3.0"

[lib]
crate-type = ["cdylib"]

[dependencies]
gstd = { git = "https://github.com/gear-tech/gear", features = ["debug"] }
scale-info = { version = "1.0.0", default-features = false, features = ["derive"] }
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
primitive-types = { version = "0.10.1", default-features = false, features = ["scale-info"]}

[profile.release]
lto = true
opt-level = 's'

open src/lib.rs file , At the beginning of the file , Import what we need Gear The library files . Take a look at this The basic structure of the program

#![feature(const_btree_new)]
#![no_std]

// External packages (crates) and internal modules import
use codec::{Decode, Encode};
use gstd::{debug, msg, prelude::*};
use scale_info::TypeInfo;

// Init function that is executed once upon contract initialization
// Here is empty
#[no_mangle]
pub unsafe extern "C" fn init() {}

// Handle function that processes the incoming message
#[no_mangle]
pub unsafe extern "C" fn handle() {}

It is the minimum structure necessary for our application to work .init() The function executes once during context initialization ,Handle The function is responsible for handling all messages passed in by the program .

Next , We're going to add a Voting structure , It will contain the main code for the handler state .

#[derive(Clone)]
pub struct State {
    votes_received: BTreeMap<String, i32>,
}

impl State {
    // Create a state
    pub const fn new() -> Self {
        Self {
            votes_received: BTreeMap::new(),
        }
    }

    // Add new candidate
    pub fn add_candidate(&mut self, candidate: String) {
        self.votes_received.insert(candidate, 0);
    }

    // Vote for the candidate by name. If candidate no exist add it
    pub fn vote_for_candidate(&mut self, name: String) {
        let counter = self.votes_received.entry(name).or_insert(0);
        *counter += 1;
    }
}

// The state itself (i.e. the variable state will be accessed through)
static mut STATE: State = State::new();

We also need to define the input used to implement 、 Output the metadata structure of the communication interface . The method described in this paper is binary mapping of interaction between different programming languages . for example , Because the program is compiled into WASM Format , So it can only understand byte language . To simplify the operation , We defined the data structure in advance , For further encoding and decoding . So , We use a special macro gstd::metadata!

gstd::metadata! {
   title: "Voting App",
   handle:
       input: Action,
   state:
       input: StateAction,
       output: StateReply,
}

Now let's start processing the incoming message . Whenever our contract receives an incoming message , We will deal with it accordingly . Let's describe handle () function :

#[derive(Debug, TypeInfo, Encode)]
pub enum StateReply {
   All(BTreeMap<String, i32>),
   VotesFor(i32),
}

#[derive(Debug, TypeInfo, Decode)]
pub enum StateAction {
   All,
   VotesFor(String),
}

// Handle function that processes the incoming message
#[no_mangle]
pub unsafe extern "C" fn handle() {
    let action: Action = msg::load().unwrap();

    debug!("Received action: {:?}", action);

    match action {
        Action::AddCandidate(name) => {
            STATE.add_candidate(name.clone());

            msg::reply((), 0, 0);

            debug!("Added new candidate: {:?}", name);
        }

        Action::VoteForCandidate(name) => {
            STATE.vote_for_candidate(name.clone());

            msg::reply((), 0, 0);

            debug!("Voted for: {:?}", name);
        }
    }
}

Now we can communicate with our program . Join and vote for the candidate . The rest is to let our program , Let all the candidates or the name of one person be displayed . So , We will use meta _ state () function , It will immediately return to the status , Without any overhead .

// The function that returns a part of memory with a state
#[no_mangle]
pub unsafe extern "C" fn meta_state() -> *mut [i32; 2] {
   let query: StateAction = msg::load().expect("failed to decode input argument");

   let encoded = match query {
       StateAction::All => StateReply::All(STATE.votes_received.clone()).encode(),

       StateAction::VotesFor(name) => {
           let votes_for_candidate = STATE
               .votes_received
               .get(&name)
               .expect("Can't find any candidate");

           StateReply::VotesFor(votes_for_candidate.clone()).encode()
       }
   };

   let result = gstd::macros::util::to_wasm_ptr(&encoded[..]);
   core::mem::forget(encoded);

   result
}

Source file :https://github.com/gear-tech/...

structure Gear Program

Our smart contract is ready ! Now it needs to be compiled and uploaded to Gear Blockchain . Let's get started !

In the voting application folder , We compiled our smart contract :

RUSTFLAGS="-C link-args=--import-memory" cargo +nightly build --release --target=wasm32-unknown-unknown

wasm-proc --path ./target/wasm32-unknown-unknown/release/voting_app.wasm

After our application is successfully compiled , The final target document is target/wasm32-unknown-unknown/release/voting-app.opt.wasm and target/wasm32-unknown-unknown/release/voting-app.meta.wasm(meta.wasm It's one used to communicate with javascript Binary interface for program interaction )

Other tools needed

install Polkadot.js Expand

Download and install Polkadot.js Browser extension :https://polkadot.js.org/exten...

Create an account

Use Polkadot.js Expand to create a new account . Don't forget to keep mnemonics and passwords in a safe place .

️ Upload program

  • Jump to https://idea.gear-tech.io/
  • Use Connect Button to connect to your account , Allow websites to access your Polkadot.js Wallet in plug-in .
  • Use “ Get test account ” Button to recharge your test account . This button can be pressed several times .
  • Upload program (.opt.wasm) and Metadata (.meta.wasm) , And give the program a meaningful name , And will gas The upper limit is set to 100,000,000. Use Polkadot.js The plug-in signs the transaction .
  • Find the program on the recently uploaded program page and copy its address .

Add new candidates / Vote for the candidate

  • stay “ All the procedures ” Find your program in the section and open the message sending form .
  • Add a new candidate or vote for an existing candidate
  • take gas The limit is set to 300,000,000, And then click Send request.

Read status

  • Jump to read the status in the program page
  • Enter the candidate's name as the number of votes to get it , Or leave the input blank , View all current candidates .

In the next article , We will learn how to use gtest The library is Gear Write test cases for smart contracts .

About GearFans

Gear It's the computing component of Boca Ecology ,GearFans yes Gear Enthusiast community .

原网站

版权声明
本文为[GearFans]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202280955508883.html