ink! 合約篇(一)| 部署 ink! 合約
- ink! 合約簡介
- 簡介
- WASM簡介
- 通過 Europa 啟動一個合約編譯沙盒環境
- 部署合約
- 編譯
- 部署
- 呼叫
- 參考鏈接
- 關于作者
實驗環境:
- Ubuntu20.04
- Europa https://github.com/patractlabs/europa
- ink!https://github.com/paritytech/ink
- polkadot explorer https://polkadot.js.org/apps/#/explorer
- rust 開發環境,因為開發程序中會遇到rust的環境,可以根據這塊的引導實作配置 https://docs.substrate.io/v3/getting-started/installation/
這篇博文主要是介紹部署ink!合約的一些流程,以及入坑的一些前提準備,
ink! 合約簡介
簡介

ink! 是構建在Substrate框架上的區塊鏈智能合約,ink! 合約會被編譯為 WebAssembly,它有著和傳統 solidity 類似的邏輯,你也可以簡單的把它理解為 Rust 版本的 Solidity,
WASM簡介

ink!合約最大的特點就是它會編譯為WebAssembly,至于為什么要選用WASM虛擬機來代替傳統的EVM虛擬機并不在這篇文章的討論范圍內,感興趣的可以移步這里,
WebAssembly 就是運行在 Web 平臺上的 Assembly,
Assembly 是指匯編代碼,是直接操作 CPU 的指令代碼,比如 x86 指令集上的匯編代碼有指令集、暫存器、堆疊等等設計,CPU 根據匯編代碼的指導進行運算,匯編代碼相當于 CPU 執行的機器碼能夠轉換成的人類適合讀的一種語言,一個典型的編譯執行鏈路是 Cpp、Rust 等編譯型語言編譯成匯編指令,再轉換成二進制機器碼由 CPU 讀取,
通過 Europa 啟動一個合約編譯沙盒環境

用于運行和除錯智能合約的 沙箱,以及用于 Substrate runtime 的沙箱框架,
我們可以通過 Europa 部署一個專門用來 部署和除錯合約的沙盒環境,在關于合約除錯方面的內容,Europa 會提供十分詳細的log資訊給我們,便于我們定位到合約代碼的問題所在,
我們可以把啟動 Europa 的程序理解為 以太坊開發solidity的時候在本地通過 geth 啟動了一個本地的測驗鏈,并且這個本地測驗鏈還會提供有 Alice Bob 賬戶,以及詳細的log資訊,
下載 Europa
> git clone https://github.com/patractlabs/europa.git
> cd europa/vendor
> git submodule update --init --recursive
編譯 Europa
> cargo build --release
> ln -s target/release/europa /bin/europa
運行 Europa
> europa --dev --tmp --ws-external --rpc-methods=unsafe
# 因為我是在wsl環境下部署的Europa,所以需要通過 --ws-external 啟動了0.0.0.0監聽,如果只需要暴露在127.0.0.1,可以自行省略,

自此我們的Europa鏈搭建并運行成功了,之后我們的合約就會部署在Europa這條鏈上,
部署合約
把合約部署在鏈上之后,我們才能對鏈上的合約方法進行呼叫,
那合約呼叫前需要經歷哪些步驟呢?
—— 編譯合約 和 部署合約
其實ink!合約呼叫的流程和以太坊呼叫合約的流程類似

編譯合約會生成在部署合約需要的 xxx.contract、xxx.wasm、metadata.json
部署合約可以根據 xxx.contract 或者 xxx.wasm 和 metadata.json 實作部署,
部署完之后就可以找一個呼叫合約的工具進行呼叫,
這里的metadata.json 可以理解為 以太坊里的 abi 檔案,xxx.wasm 可以理解為 以太坊里的 bin 檔案,至于xxx.contract 可以理解為 abi 檔案+bin 檔案的結合,
編譯
我們可以通過ink!的cli工具(cargo-contract)實作編譯合約的目的,并獲得 xxx.contract、xxx.wasm、metadata.json 檔案,
環境配置
> rustup component add rust-src --toolchain nightly
> rustup target add wasm32-unknown-unknown --toolchain nightly
> sudo apt install binaryen
安裝 cargo-contract
> cargo install cargo-contract --vers ^0.15 --force --locked
通過 cargo-contract 獲取 example例子
> cargo contract new flipper
> cd flipper/
只要是官方庫內的example都可以通過 cargo contract new xxx 獲取,這里我們以flipper合約為例,

flipper 合約內容
flipper合約是一個僅包含單個bool值的簡單合約,它提供了方法 flip() 翻轉它的值從 true 到 false(反之亦然)和 get() 回傳當前bool值的狀態,
#![cfg_attr(not(feature = "std"), no_std)]
use ink_lang as ink;
#[ink::contract]
mod flipper {
/// Defines the storage of your contract.
/// Add new fields to the below struct in order
/// to add new static storage fields to your contract.
#[ink(storage)]
pub struct Flipper {
/// Stores a single `bool` value on the storage.
value: bool,
}
impl Flipper {
/// Constructor that initializes the `bool` value to the given `init_value`.
#[ink(constructor)]
pub fn new(init_value: bool) -> Self {
Self { value: init_value }
}
/// Constructor that initializes the `bool` value to `false`.
///
/// Constructors can delegate to other constructors.
#[ink(constructor)]
pub fn default() -> Self {
Self::new(Default::default())
}
/// A message that can be called on instantiated contracts.
/// This one flips the value of the stored `bool` from `true`
/// to `false` and vice versa.
#[ink(message)]
pub fn flip(&mut self) {
self.value = !self.value;
}
/// Simply returns the current value of our `bool`.
#[ink(message)]
pub fn get(&self) -> bool {
self.value
}
}
// test file ... 被我省略了
}
編譯flipper合約
回到剛才flipper檔案夾處,
開始編譯合約
> cargo +nightly contract build --keep-debug-symbols --optimization-passes=0

編譯完成之后,我們可以在 ./target/ink 下找到 flipper.contract、flipper.wasm、metadata.json

自此編譯作業就完成了,下面我們要利用這幾個檔案將合約部署在之前運行的 Europa 測驗鏈上,

—— ink!-example https://github.com/paritytech/ink/tree/master/examples
部署
接下來我們可以直接通過 polkadot explorer https://polkadot.js.org/apps/#/explorer 實作合約的部署了,
切換網路到 Eruopa 鏈

在Contract模塊下實作合約的部署


在這里需要注意一點,我們可以通過兩種組合實作部署,
一種是通過 flipper.contract 實作部署

另外一種是通過 flipper.wasm 和 metadata.json 實作部署,

上傳完之后就可以設定初始內容了,設定完之后就可以通過deploy實作部署


自此我們的合約部署成功了,
呼叫

通過Alice呼叫get方法,得知 bool值 是 true,

通過呼叫flip() 方法實作bool值的取反,


成功!下篇我會介紹如何通過go sdk來呼叫鏈上的合約,并介紹一下ink!范式下的合約呼叫三要素,
參考鏈接
https://www.bilibili.com/video/BV1HL411u772?spm_id_from=333.999.0.0
https://www.bilibili.com/video/BV1RX4y1V7W9?spm_id_from=333.999.0.0
https://docs.substrate.io/tutorials/v3/ink-workshop/pt1/#/0/setup
https://docs.patract.io/en/europa/intro/europa-cli
https://mp.weixin.qq.com/s/lMj1MxYPJCaw7DFORctPLw
https://mp.weixin.qq.com/s?__biz=MzI3MzYxNzQ0Ng==&mid=2247485373&idx=1&sn=7953d3665e1170d1bfd7ce29853f8bed&chksm=eb21c0f4dc5649e29945941821150e608a3a50269f509d8c34da3cce8725e62b0a1b88b3ca33&scene=21#wechat_redirect
關于作者
作者的聯系方式:
微信:thf056
qq:1290017556
郵箱:1290017556@qq.com
你也可以通過 github | csdn | @新浪微博 關注我的動態
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/357186.html
標籤:區塊鏈
上一篇:讀書系列2021
下一篇:時間筆記 - 11月11日
