Technology Viewpoint | Want to develop dApp with Wasm? You have to read the introductory tutorial (1)
In the previous technical point of view article, we introduced how to implement a simple red envelope contract in C++ to help developers understand how to use C++ language to develop contracts on Ontology. In addition, we have briefly introduced development considerations for using the Rust language.
In this technical point of view and later related series, we will detail how to develop the Ontology Wasm contract using the Rust language. In this technical point of view, we will briefly introduce how to build and use contract templates for development.
First, the environment to build
In order to improve the efficiency of development, it is recommended to prepare the following development environment before the development contract.
- Technical Perspectives | Contract Upgrade for Python Smart Contract Tutorial
- How To | Build a Zero-Dependent Application on IPFS (Vol. 2)
- Technical Perspectives | Python Smart Contract Tutorial Native Contract Call
- Rust development environment (required)
- Integrated development environment (recommended)
- Local Wasm Contract Test Node (recommended)
One thing to note here is that the local test node can be built to facilitate contract testing. At the same time, you can monitor the contract running information in the node log by adding debug information to the contract. Of course, if you feel that building a test node is complicated, we can also use the Ontology test network for contract testing.
1.1 Rust development environment to build
The Rust development environment can be completed in the following steps:
1. Install rustup . For Linux, Mac OS, and other Unix-like systems, you can execute the following commands directly and follow the on-screen prompts.
Curl https://sh.rustup.rs -sSf | sh
If it is a system such as Windows, please visit the official website to download the appropriate version to install.
2. Install the rust compiler .
After installing rustup, you can install the rust compiler with the following command:
Rusup install nightly
Also, set the default compiled version to nightly:
Rustus default nightly
3. Install the Wasm32 compilation target .
Developers can install the Wasm32 compilation target with the following command:
Rusup target add wasm32-unknown-unknown
- The specific installation method is as follows: cargo install –git=https://github.com/ontio/ontio-wasm-build
1.2 Installing the Integrated Development Environment
1.3 Local test node setup
Please refer to the Ontology official documentation for this section: Local Test Node Environment.
Second, the use of contract templates to develop Wasm contracts
To use the contract source code developed by Rust to run on the Ontology chain, go through the following steps:
1. You need to compile the source code into Wasm bytecode first.
2. Optimize the Wasm bytecode using the ontio-wasm-build tool.
3. Deploy the optimized Wasm bytecode to the chain.
4. Make a call to the method in the contract.
Below is a simple example of developing a Wasm contract using a contract template to introduce the entire process.
2.1 Obtaining Wasm Contract Template
In order to facilitate developers to start Ontology Wasm contract development, we provide a contract template (Rust version), developers only need to clone the code, and then add their own contract logic.
Git clone https://github.com/ontio/rust-wasm-contract-template.git
. ├── .cargo │ └── config ├── Cargo.toml ├── build.sh └── src └── lib.rs
We explain some of these files:
- The configuration file of the contract compile is configured in the config file below the .cargo folder. The contents of the config file are as follows:
[target.wasm32-unknown-unknown] Rustflags = [ "-C", "link-args=-z stack-size=32768" ]
[target.wasm32-unknown-unknown] indicates the compilation target, rustflags configures the compiled link parameters. Here, the default stack size is set to 32768, which is 32 kb, and the maximum stack size that the contract can use during the running process.
-
The Cargo.toml file is some basic configuration information for the contract, and its contents are as follows:
[package] Name = "rust-wasm-contract-template" Version = "0.1.0" Authors = ["name <[email protected]>"] Edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
Crate-type = ["cdylib"] #Compile as a dynamic link library
[dependencies]
Ontio-std = {git = "https://github.com/ontio/ontology-wasm-cdt-rust"}
[features]
Mock = ["ontio-std/mock"]
-
The build.sh file encapsulates the functions of compiling the contract and optimizing the contract. After the contract is developed, executing the script will place the optimized contract bytecode under the output directory. -
Src/lib.rs is used to write contract logic code. The code in the contract template is as follows:
#![no_std] Use ontio_std::runtime;
#[no_mangle]
Fn invoke() {
Runtime::ret(b"hello");
}
-
#![no_std] means to mask the interfaces in the rust std library, but developers can call the apis in the rust core library. -
#[no_mangle] indicates that the invoke function is exported when compiled into wasm bytecode. The invoke function is the entry function of the Ontology Wasm contract and needs to be exported. -
The runtime module encapsulates the interface between the contract and the chain, and runtime::ret() is used to return the result of the contract execution to the caller.
2.2 Compilation contract
Developers can implement contract compilation and contract bytecode optimization directly by executing the build.sh script.
./build.sh
If the following permission error occurs during the execution:
-bash: ./build.sh: Permission denied
Sudo chmod +x ./build.sh
After the execution is successful, the output directory is generated in the current directory. The directory structure of output is as follows:
├── output │ ├── rust_wasm_contract_template.wasm │ └── rust_wasm_contract_template.wasm.str
Where rust_wasm_contract_template.wasm is the Wasm bytecode file generated by our compiled contract source code. Rust_wasm_contract_template.wasm.str is a hex-encoded file of Wasm bytecode.
2.3 Deployment contract
The compiled Wasm contract needs to be deployed on the chain to run. We can deploy the above contract bytecode file to the test network, or the local test node. Let's take the example of deploying to the local test network:
First, start the local test node, we need to be a wallet file before starting:
./ontology account add
./ontology --testmode --loglevel 1
$ ./ontology contract deploy --vmtype 3 --code ./rust_wasm_contract_template.wasm.str --name helloworld --author "author" --email "email" --desc "desc" --gaslimit 22200000 Password: Deploy contract: Contract Address: 0be3df2e320f86f55709806425dc1f0b91966634 TxHash: bd83f796bfd79bbb2546978ebd02d5ff3a54c2a4a6550d484689f627513f5770
Tip:
Using './ontology info status bd83f796bfd79bbb2546978ebd02d5ff3a54c2a4a6550d484689f627513f5770' to query transaction status.
2.4 Test Contract
Now let's call the method in the contract and execute the following command:
$ ./ontology contract invoke --address 0be3df2e320f86f55709806425dc1f0b91966634 --vmtype 3 --params '' --version 0 --prepare Invoke:346696910b1fdc2564800957f5860f322edfe30b Params:null Contract invoke successfully Gas limit: 20000 Return: 68656c6c6f (raw value)
In order to be able to see the result of the contract execution return, we added a –prepare tag to the command to indicate that the transaction is a pre-executed transaction.
As you can see, on the command line, we get 68856c6c6f, which is the hex encoding format of the expected result hello, we only need to use hex decoding to get the expected result.
In this issue of technical point of view, we briefly introduced how to use the Rust language for Wasm development on Ontology, how to build the environment and use contract templates for development. In addition, a new version of SmartX that supports Ontology Wasm contract deployment and invocation is under development and will be available soon. Its on-line will greatly facilitate developers to deploy Ontology Wasm contracts and call related functions. Third, the conclusion
We will continue to update Blocking; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles
- The most heavy chain rule defect: your main chain I am the master
- Getting started with blockchain | Hash lock for cross-chain technology solutions
- Technical Perspectives | How much does the Python Smart Contract Execution API know?
- Comparison of IPFS and EdgeFS for Secure Edge/IoT Computing Use Cases
- Five major problems read through the PoA consensus algorithm
- Analysis | Pre-selection and pre-submission mechanisms for Byzantine fault-tolerant consensus
- Unlock Bitcoin for more apps, Miniscript yesterday, today and tomorrow!