【Solana 開発】Solana のスマートコントラクト開発環境を作ろう②【Web3 アプリ】

[【Solana 開発】Solana のスマートコントラクト開発環境を作ろう①【Web3 アプリ】](https://qiita.com/FumiSOULs/items/596afeafb6fd4bb689b3)

に続いて、Solana スマートコントラクト開発のために Anchor をインストールします。

Web3, 特に dApp の世界ではデータの扱い方が大きく変わります。
もちろん、`Web2` で得たスキルや知識はそのまま `Web3` でも輝きます☺

ざっくりですが、これまでのデータの捉え方は、
それぞれの中央管理サーバーにデータの所有があるのに対し、
`Web3` ではデータをユーザーが所有します。
![](https://storage.googleapis.com/zenn-user-upload/28668c51f148-20220824.png)
![](https://storage.googleapis.com/zenn-user-upload/00009cc46636-20220824.png)

このような新たな概念でデータ構造を考えていくように筆者も日々脳内転生に励んでいます。

それでは Anchor の開発環境を整えてみます。

## `avm` のインストール
```bash
$ cargo install --git https://github.com/project-serum/anchor avm --locked --force
```

Linuxなどの場合以下のライブラリのインストールが必要になることがあります。
`cargo install` が失敗した場合、以下のコマンドを試してみて下さい。
```bash
$ sudo apt-get update && sudo apt-get upgrade && sudo apt-get install -y pkg-config build-essential libudev-dev
```

## Anchor のインストールとバージョン管理
```bash
$ avm install latest
$ avm use latest
```

バージョンの確認
```bash
$ anchor --version
```

## Anchor プロジェクトを作る

`anchor init {プロジェクト名}` で新規 Anchor プロジェクトを作成します。
ここでは `first_contract` というプロジェクト名を使います。

```bash
$ anchor init first_contract
yarn install v1.22.19
warning package.json: No license field
info No lockfile found.
warning No license field
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
warning "@project-serum/anchor > @solana/web3.js > react-native-url-polyfill@1.3.0" has unmet peer dependency "react-native@*".
[4/4] Building fresh packages...
success Saved lockfile.
Done in 14.26s.
Initialized empty Git repository in /home/fumi/dev/rust/first_contract/.git/
first_contract initialized
```

`anchor init` が失敗する場合は `node` と `yarn` がインストールされていることを確認してください。

Node バージョン確認
```bash
$ node -v
v18.7.0
```
Yarn バージョン確認
```bash
$ yarn -v
1.22.19
```

## Anchor フレームワークの構造
`anchor init` で生成されたプロジェクトのディレクトリ構造は以下のようになっています。

```tree
├── Anchor.toml
├── Cargo.lock
├── Cargo.toml
├── app
├── migrations
│   └── deploy.ts
├── package.json
├── programs
│   └── first_contract
│       ├── Cargo.toml
│       ├── Xargo.toml
│       └── src
│           └── lib.rs
├── tests
│   └── first_contract.ts
├── tsconfig.json
└── yarn.lock
```

スマートコントラクトを実際に書き込む部分は `programs` ディレクトリになります。


## スマートコントラクトのテンプレート

デフォルトで以下のコントラクトが生成されます。
Achor フレームワークでは基本的に、
コントラクトのロジック部分のみを書けば動作するようにしてくれています。

`programs/first_contract/src/lib.rs`
```rust
use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod first_contract {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize {}
```

このままビルドしてテストをすることができるので、
まずは動作確認をしてみます。

## Anchor Test の実行

`anchor test` コマンドで、
ビルド、デプロイ、テストが実行されます。

```bash
$ anchor test
  first_contract
Your transaction signature 3xFXGqebu8qNSD8jM1iuxfe81fr4CvpVE9d3DTAmpDCjHTNgQpnv2DgqYj4EEDJHMSZuLku7anpNad3P7r7vrzmT
    ✔ Is initialized! (429ms)

  1 passing (431ms)

Done in 5.58s.
```

テストが起動しない場合には以下のパッケージをインストールしてみてください。
```bash
yarn add ts-mocha
```

Solana のネットワークは主に以下の4つがあります。

|  環境  |  url  |
| ---- | ---- |
|  ローカル環境  |  localhost  |
|  テスト環境  |  testnet  |
|  DEV環境  |  devnet  |
|  本番環境  |  testnet  |

その他にも `GenesysGo` などが提供するネットワークもあります。

`solana config get` で現在接続しているネットワークを確認してみます

```bash
$ solana config get
Config File: ~/.config/solana/cli/config.yml
RPC URL: http://localhost:8899 
WebSocket URL: ws://localhost:8900/ (computed)
Keypair Path: ~/.config/solana/id.json 
Commitment: confirmed 
```

## ローカルネットワークを使う場合

### Solana Test Validator の起動

別のターミナルでSolana のローカルテスト環境を用意します。

```bash
$ solana-test-validator
```

### Solana ネットワークを変更する

```bash
$ solana config set --url localhost
```

### Anchor ビルド＆デプロイ

```bash
$ anchor build
$ anchor deploy
```

これで Solana スマートコントラクト開発を行う準備が整いました🎉