Swanky Suite  - WASM スマートコントラクト開発環境準備

この記事は、WASM（WebAssembly）を使ってスマートコントラクト開発する際の便利なツールとして、**Swanky Suite** を使うための準備について書いています。

# はじめに

**Swanky Suite** は、日本発のパブリック・ブロックチェーンである「**Astar Network**」のコミュニティで開発されており、Wasmスマートコントラクト開発者のための「**オールインワン**」ツールを目指しています。いわゆる、**IDE** です。

https://medium.com/astar-network/swanky-the-all-in-one-wasm-tool-50c0ed9f07a6

記事を書いている時点で、swanky-cli の最新バージョンは **v1.0.7** です。

https://github.com/AstarNetwork/swanky-cli/releases

# 開発環境の目標

この記事では、以下の環境を作り上げる事を目標とします。

> Substrate フレームワークで作られたブロックチェーン（Shiden/Astar Network, 等）のために、WASM スマートコントラクトを開発するための環境作り

| ITEM | INFO |
|:-----------:|:------------|
| OS       | Windows 10 / 11|
| Windows Subsystem for Linux| Ubuntu 22.04.1 LTS| 
| 開発言語| ink! (Substrate フレームワークで作られたブロックチェーン用の Rust ベースのスマートコントラクト開発言語）|
| 統合開発環境（IDE）| Swanky Suite |


**flipper** テンプレートでテストプロジェクトを作ってコンパイルするところまで確認します。


# 今回の環境

**Windows Subsystem for Linux** の環境で導入します。Linux / macOS 環境で使うよりもなにかと考慮点が多くあったため、こちらをターゲットとしました。

* Ubuntu 22.04.01 LTS on WSL

# 事前準備

Swanky Suite を導入する前の準備をします。
以下の情報を元にしています。

* https://docs.astar.network/docs/wasm/sc-dev/env-setup
* https://docs.substrate.io/install/windows/
* https://learn.microsoft.com/en-us/windows/wsl/setup/environment
* https://use.ink/getting-started/setup/
* https://github.com/paritytech/cargo-contract#installation

## WSL 準備

お使いの WSL = Windows Subsystem for Linux が使える Windows マシンを用意します。Windows 10 、Windows 11 をお使いであれば導入は容易でしょう。
WSL のインストールの詳細は割愛しますが以下をご参照ください。

https://learn.microsoft.com/ja-jp/windows/wsl/install


```Poiwershell: PowerShell
> wsl --install
```
## Ubuntu インストール
記事を書いている時点で最新の Ubuntu 22.04.01 LTS をインストールしています。これは Microsoft Store から容易に導入可能です。
（このインストールは割愛します。）

## Ubuntu インストール後のセットアップ
Ubuntu インストール後、スタートメニューからUbuntuを起動します。少し待った後、**一般ユーザの作成**と、sudo で使う**パスワード**を設定して、利用可能になります。

![w1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75458/d0b97422-376b-3423-5cbe-47ebc5754cc1.png)


## Rust 準備

**Rust**  をインストールします。

> ちなみに WASM の開発言語では、Rust が一番使われています。 [The State of WebAssembly 2022](https://blog.scottlogic.com/2022/06/20/state-of-wasm-2022.html)

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ sudo apt update
hoge@DESKTOP-QVCDBPV:~$ sudo apt install --assume-yes git clang curl libssl-dev llvm libudev-dev make protobuf-compiler
hoge@DESKTOP-QVCDBPV:~$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
info: downloading installer

Welcome to Rust!

This will download and install the official compiler for the Rust
programming language, and its package manager, Cargo.

Rustup metadata and toolchains will be installed into the Rustup
home directory, located at:

  /home/hoge/.rustup

This can be modified with the RUSTUP_HOME environment variable.

The Cargo home directory is located at:

  /home/hoge/.cargo

This can be modified with the CARGO_HOME environment variable.

The cargo, rustc, rustup and other commands will be added to
Cargo's bin directory, located at:

  /home/hoge/.cargo/bin

This path will then be added to your PATH environment variable by
modifying the profile files located at:

  /home/hoge/.profile
  /home/hoge/.bashrc

You can uninstall at any time with rustup self uninstall and
these changes will be reverted.

Current installation options:


   default host triple: x86_64-unknown-linux-gnu
     default toolchain: stable (default)
               profile: default
  modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
> 1 #・・・ 入力して Enter

（中略）

  stable-x86_64-unknown-linux-gnu installed - rustc 1.66.0 (69f9c33d7 2022-12-12)


Rust is installed now. Great!

To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).

To configure your current shell, run:
source "$HOME/.cargo/env"
hoge@DESKTOP-QVCDBPV:~$
```

Cargo を含めた形でシェルの環境を更新します。
> Cargo は Rust のビルドシステム兼パッケージマネージャです。

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ source ~/.cargo/env
```

Rust のバージョン確認をします。

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ rustc --version
rustc 1.66.0 (69f9c33d7 2022-12-12)
```

rustup をつかって、最新の安定したバージョンをデフォルトのツールチェーンとして使用するように Rust ツールチェーンを構成します。

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ rustup default stable
info: using existing install for 'stable-x86_64-unknown-linux-gnu'
info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'

  stable-x86_64-unknown-linux-gnu unchanged - rustc 1.66.0 (69f9c33d7 2022-12-12)

hoge@DESKTOP-QVCDBPV:~$ rustup update
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: checking for self-updates

  stable-x86_64-unknown-linux-gnu unchanged - rustc 1.66.0 (69f9c33d7 2022-12-12)

info: cleaning up downloads & tmp directories
```

Rust ツールチェーンのバージョンに nightly を追加し、開発環境として、WASM ターゲット nightly を追加します。

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ rustup update nightly

（中略）

  nightly-x86_64-unknown-linux-gnu installed - rustc 1.68.0-nightly (9c07efe84 2022-12-16)

info: checking for self-updates

hoge@DESKTOP-QVCDBPV:~$ rustup target add wasm32-unknown-unknown --toolchain nightly

（中略）

info: downloading component 'rust-std' for 'wasm32-unknown-unknown'
info: installing component 'rust-std' for 'wasm32-unknown-unknown'
 18.7 MiB /  18.7 MiB (100 %)   9.0 MiB/s in  2s ETA:  0s
```

構成された、Rust ツールチェーンの確認をします。

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ rustup show
Default host: x86_64-unknown-linux-gnu
rustup home:  /home/hoge/.rustup

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu (default)
nightly-x86_64-unknown-linux-gnu

active toolchain
----------------

stable-x86_64-unknown-linux-gnu (default)
rustc 1.66.0 (69f9c33d7 2022-12-12)
```

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ rustup +nightly show
Default host: x86_64-unknown-linux-gnu
rustup home:  /home/hoge/.rustup

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu (default)
nightly-x86_64-unknown-linux-gnu

installed targets for active toolchain
--------------------------------------

wasm32-unknown-unknown
x86_64-unknown-linux-gnu

active toolchain
----------------

nightly-x86_64-unknown-linux-gnu (overridden by +toolchain on the command line)
rustc 1.68.0-nightly (9c07efe84 2022-12-16)
```

## ink! CLI インストール

今回の環境だと、途中でエラーが発生するため、**pkg-config** を先にインストールします。

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ sudo apt-get install pkg-config
```
### cargo-contract インストール

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ cargo install cargo-dylint dylint-link

（中略）

  Installing /home/takeshi/.cargo/bin/dylint-link
   Installed package `dylint-link v2.1.1` (executable `dylint-link`)
     Summary Successfully installed cargo-dylint, dylint-link!

hoge@DESKTOP-QVCDBPV:~$ cargo install cargo-contract --force --locked

  Installing cargo-contract v1.5.1
warning: package `blake2 v0.10.4` in Cargo.lock is yanked in registry `crates-io`, consider running without --locked
warning: package `cpufeatures v0.2.2` in Cargo.lock is yanked in registry `crates-io`, consider running without --locked

（中略）

   Compiling parity-wasm v0.45.0
   Compiling clap v3.2.16
   Compiling subxt v0.23.0
    Finished release [optimized] target(s) in 2m 46s
  Installing /home/hoge/.cargo/bin/cargo-contract
   Installed package `cargo-contract v1.5.1` (executable `cargo-contract`)

```

## Node.js アップデート

この記事作成時点では、後述の **swanky-cli** インストール時に必要なアップデートだったため実行してます。

* この Ubuntu 22.04.1 の nodejs バージョンが低い（12.22.9）
* リポジトリを更新し、アップデートされた nodejs 入れてから、npm をアップデート（8.19.2 -> 9.2.0）


```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - 
hoge@DESKTOP-QVCDBPV:~$ sudo apt show nodejs
hoge@DESKTOP-QVCDBPV:~$ sudo apt-get install -y nodejs
hoge@DESKTOP-QVCDBPV:~$ node -v
v18.12.1

hoge@DESKTOP-QVCDBPV:~$ sudo npm install -g npm@9.2.0
hoge@DESKTOP-QVCDBPV:~$ npm -v
9.2.0
```

# Swanky Suite

## swanky-cli インストール 

この記事投稿時点の、v1.0.7 を使っています。

```shell-session: Bash
hoge@DESKTOP-QVCDBPV:~$ sudo npm install -g @astar-network/swanky-cli@1.0.7

added 411 packages in 30s

49 packages are looking for funding
  run `npm fund` for details

hoge@DESKTOP-QVCDBPV:~$ swanky --version
@astar-network/swanky-cli/1.0.7 wsl-x64 node-v18.12.1
```

## yarn のインストール

``swanky init`` を実行時に一部エラーがでるのでその回避策として、yarn をインストールしておきます。

```shell-session: Bash
hoge@DESKTOP-VG4GHSG:~$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
hoge@DESKTOP-VG4GHSG:~$ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
hoge@DESKTOP-VG4GHSG:~$ sudo apt-get update && sudo apt-get install yarn

hoge@DESKTOP-VG4GHSG:~$ yarn -v
1.22.19
```

## テストプロジェクトを作りコンパイル

※ ``swanky init`` をする前に、git の情報登録が必要です。

```shell-session: Bash
hoge@DESKTOP-VG4GHSG:~$ git config --global user.name "hoge"
```

``swanky init`` 実行後、対話式となるので、以下のように選択、入力して進めます。

```shell-session: Bash
hoge@DESKTOP-VG4GHSG:~$ swanky init test_pj
? Which contract language should we use? ink
? Which contract template should we use initially? flipper
? What should we name your initial contract? sample
? What is your name? hoge
? What is your email?
? Do you want to download Swanky node? Yes
✔ Checking dependencies OK
✔ Copying template files OK
✔ Processing templates OK
✔ Initializing git OK
✔ Downloading Swanky node OK
✔ Installing dependencies OK
✔ Writing config OK
🎉 😎 Swanky project successfully initialised! 😎 🎉
hoge@DESKTOP-VG4GHSG:~$
```

コンパイル時に、エラーが発生するため、下記を実行します。

* 標準ライブラリでビルドできない: rustup で rust-src を開発環境に追加
* wasm-opt がない: binaryen をインストール（https://github.com/WebAssembly/binaryen#tools）


```shell-session: Bash
hoge@DESKTOP-VG4GHSG:~$ rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
info: downloading component 'rust-src'
info: installing component 'rust-src'

hoge@DESKTOP-VG4GHSG:~$ sudo apt-get install binaryen
```

作られたディレクトリに移動して、コンパイルします。

```shell-session: Bash
hoge@DESKTOP-VG4GHSG:~$ cd test_pj

hoge@DESKTOP-VG4GHSG:~/test_pj$ swanky contract compile sample -v

======== Found contracts ========
        sample
======== Compiling sample ========
Checking with toolchain `nightly-2022-06-30-x86_64-unknown-linux-gnu`
   Compiling proc-macro2 v1.0.47
   Compiling unicode-ident v1.0.5

（中略）

   Compiling metadata-gen v0.1.0 (/tmp/cargo-contract_dxfxum/.ink/metadata_gen)
    Finished release [optimized] target(s) in 17.88s
     Running `target/ink/release/metadata-gen ''`
======== Compiled sample ========
======== Compiled all contracts ========
======== Compiling Typechain' code ========
@polkadot/util has multiple versions, ensure that there is only one installed.
Either remove and explicitly install matching versions or dedupe using your package manager.
The following conflicting packages were found:
        cjs 10.2.1      node_modules/@polkadot/util/cjs
        cjs 9.7.2       node_modules/@supercolony/typechain-polkadot/node_modules/@polkadot/util/cjs
======== Compiled Typechain' code ========
✔ Contract compiled successfully
✔ Copying artifacts OK

hoge@DESKTOP-VG4GHSG:~/test_pj$ 
```


# 所感

今回の環境（Windows - WSL）では、エラーを取り除きながら環境づくりをするために、そこそこ回り道をしましたがきちんとコンパイルを完了するところまでできました。



以上、