-
Notifications
You must be signed in to change notification settings - Fork 6
Develop Guide
Sewup helps you develop ewasm contract easier, and providing a lot of macros to make things smooth.
Here is the guide to help you using this macro.
You can initialize the project with cargo-sewup
(required version >0.1.9)
Also you can init sewup project with different mode of ewasm_main
with --mode
or -m
option, the difference mode will return different output, the return output maybe be wrapped by the result of Rust, or unwrap automatically.
If you only care the contract is executed fail or not, you can use default mode without -m
or --mode
option.
- Install Rust nightly and wasm32 target
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup default nightly-2021-11-29
rustup target add wasm32-unknown-unknown
- Install cargo-sewup
cargo install cargo-sewup
- Initialize project
- In current folder
cargo sewup init -m <auto|rusty>
- In specific folder
cargo sewup init -p /path/to/folder -m <auto|rusty>
Following is the minimal setting to initial a sewup project.
# Cargo.toml
[package]
name = "hello-contract"
[lib]
path = "src/lib.rs"
crate-type = ["cdylib"]
[dependencies]
sewup = { version = "*", features = ['kv'] }
sewup-derive = { version = "*", features = ['kv'] }
anyhow = "1.0"
[profile.release]
incremental = false
panic = "abort"
lto = true
opt-level = "z"
[profile.release.package.hello-contract] # package name
incremental = false
opt-level = "z"
# Following features helps are used when building or testing a contract
[features]
constructor = [] # required
constructor-test = [] # required
# sewup.toml
# Following section including the parameters to deploy the contract
[deploy]
url = "http://localhost:8545" # url for rpc node
private = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # private key
address = "0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # account address
# gas = 5000000 # optional
# gas_price = 1 # optional
Place .cargo/config file in your project to specify the flags for build.
Here is minimize example for writing a contract with sewup
// lib.rs
use anyhow::Result;
use sewup::primitives::Contract;
use sewup_derive::{ewasm_constructor, ewasm_fn, ewasm_fn_sig, ewasm_main, ewasm_test};
#[ewasm_constructor]
fn constructor() {
// do something you want when the contract deploy on chain
}
#[ewasm_fn]
fn hello() -> Result<String> {
let target = "world";
let greeting = "hello ".to_string() + sewup::ewasm_dbg!(target);
Ok(greeting)
}
#[ewasm_main(auto)]
fn main() -> Result<String> {
let contract = Contract::new()?;
let greeting = match contract.get_function_selector()? {
ewasm_fn_sig!(hello) => hello()?,
_ => panic!("unknown handle"),
};
Ok(greeting)
}
#[ewasm_test]
mod tests {
use super::*;
use sewup_derive::ewasm_auto_assert_eq;
#[ewasm_test]
fn test_get_greeting() {
ewasm_auto_assert_eq!(hello(), "hello world".to_string());
}
}
Sewup try to help web developer develop blockchain applications as easier as before.
The first thing we try to help is the storage type, you can check out Storage Guide(storage guide) to learn more.
In traditional block chain contract developing, developers need to deploy the compiled contract on test net. We want the developing experience follows the Rust way, and developer can test the contract as normal Rust project without handling the deploying issues.
To do this, we are using WasmEdge as the runtime environment, WasmEdge also is a VM/runtime for several block chain network, edge computing platform and AI platform, for example, ParaState Besides, the test frame will automatically setup the contract caller, which still can be customized I will mentions in details later.
You can go to example/default-contract, and run Cargo test
Here is the test result you will see.
running 3 tests
test tests::_compile_runtime_test ... ok
test tests::_compile_constructor_test ... ok
test tests::test_execute_basic_operations ... ok
The test mod
and the test case are decorated by wasm_test,
namely thing normally decorated by #[cfg(test)]
are changed to #[wasm_test]
.
This macro will setup the runtime for you and also add these two test case, _compile_runtime_test
and _compile_constructor_test
.
These two test cases will help you to check on the constructor ewasm and the runtime ewasm can build correctly or not.
graph TD
A[Cargo test] -->|compile| B[Constructor ewasm]
A[Cargo test] -->|compile| C[Runtime ewasm]
subgraph handle by Sewup macros
B --> |execute once at first| D[Setup runtime]
C --> |execute in each assert macro|D[Setup runtime]
end
D --> |run| E(Test Case)
When testing on the test_execute_basic_operations
test case, the runtime will be setup and run the constructor ewasm at first for each test case,
And then following assert macros will call the one of the handlers of the runtime ewasm and assert the result in different way:
ewasm_assert_eq,
ewasm_assert_ok,
ewasm_auto_assert_eq,
ewasm_rusty_assert_ok.
Choosing the macro based on the macro attribute you provide in ewasm_main, you can follow the one of the examples, and the basic ideal on running test case is still the same.
It is recommended to develop sewup project with test driven flow.
You can always use cargo test
to make sure every thing works as you expected.
Once you got errors on compiling runtime or compiling constructor.
You can use following command to debug your project.
cargo build --target=wasm32-unknown-unknown
cargo build --features=constructor --target=wasm32-unknown-unknown
If you are you want to print out things in the contract, you may use sewup::ewasm_dbg!
in your contract, then run
cargo test -- --nocapture
to see the debug print of the instance you inspect.
Some struct
in sewup
, sewup-derive
are not provided Debug
trait, if you are not enabled the feature debug
on the crate.
We highly recommend you to go through our hackathons and slides listed in the readme.