ink 合约篇(一)| 部署 ink 合约

实验环境:

  1. Ubuntu20.04
  2. Europa https://github.com/patractlabs/europa
  3. ink!https://github.com/paritytech/ink
  4. polkadot explorer https://polkadot.js.org/apps/#/explorer
  5. 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.contractxxx.wasmmetadata.json
部署合约可以根据 xxx.contract 或者 xxx.wasmmetadata.json 实现部署。
部署完之后就可以找一个调用合约的工具进行调用。

这里的metadata.json 可以理解为 以太坊里的 abi 文件,xxx.wasm 可以理解为 以太坊里的 bin 文件,至于xxx.contract 可以理解为 abi 文件+bin 文件的结合。

编译

我们可以通过ink!的cli工具(cargo-contract)实现编译合约的目的,并获得 xxx.contractxxx.wasmmetadata.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() 翻转它的值从 truefalse(反之亦然)和 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.contractflipper.wasmmetadata.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
邮箱:[email protected]

你也可以通过 github | csdn | @新浪微博 关注我的动态

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>