SolanaでNFTコレクションを作成してミントページでミントするまで

## はじめに
SolanaでNFTを作成する場合、Metaplexと呼ばれるプラットフォームがよく使われています。
https://www.metaplex.com

Metaplexが提供している[Candy Machine](https://docs.metaplex.com/programs/candy-machine)というスマートコントラクトを使って、ジェネレーティブNFTコレクションを作成し、ミントページでミントするまでを実施したいと思います。
また、今回はMacOSを前提としています。

## アセットを用意する
まずはアセットを用意します。アセットはHashlipsというOSSを使って簡単に作成することができます。
[GitHub - HashLips/hashlips_art_engine: HashLips Art Engine is a tool used to create multiple different instances of artworks based on provided layers.](https://github.com/HashLips/hashlips_art_engine)
作成方法については、HashlipsのReadmeに記載されていますが、後日別記事で解説しようと思います。

今回は以下のように# 0 ~ # 4の5組のアセットを用意しました。
Candy Machineを利用するためには、0からの連番でアセットを用意する必要があります。
![616835CB-B476-4D80-B725-F6E28FC936B9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626975/462b3504-9fe8-2b25-e666-4f034fa69115.png)
pngファイル ➡︎ NFTの画像
jsonファイル ➡︎ メタデータ
pngとjsonのファイルの組は1つのフォルダ内にまとめて格納する必要があります。

## Solana CLIのインストール
ウォレットの作成や、SOLエアドロップのためにSolana CLIをインストールします。
```
sh -c "$(curl -sSfL https://release.solana.com/v1.14.13/install)"
```

バージョンについては日々アップデートされるので、インストールする際は以下を参照した方がいいと思います。
[Install the Solana Tool Suite | Solana Docs](https://docs.solana.com/cli/install-solana-cli-tools)

## ウォレットを作成する
以下コマンドを実行して、ウォレットを作成します。
```
solana-keygen new --outfile ./my-keypair.json
```

カレントディレクトリにmy-keypair.jsonというファイルが作成されます。これは、決して他人に渡したり、中身を教えてはいけないファイルになります。
もし渡してしまうと、ウォレット内のトークンを全て奪われることになります。

以下コマンドで作成されたウォレットのアドレスを確認することができます。
```
solana-keygen pubkey ./my-keypair.json
```

私の場合、
```
7ZsTkwHmm4WutDaoEjf5kyptBqbDzBo4TSo1GCn2U1We
```
が表示されたので、上記が作成されたウォレットのアドレスということになります。

## SOLエアドロップ
Solanaには以下の3つのネットワークが用意されています。
* Mainnet Beta
* Devnet
* Testnet

Mainnet Betaは本番環境なので、本物のトークンが利用されます。それに対し、DevnetとTestnetは偽物のトークンが利用され、ネイティブトークンであるSOLも自由にエアドロップできます。

以下コマンドでSOLをエアドロップできます。
```
solana airdrop 1 7ZsTkwHmm4WutDaoEjf5kyptBqbDzBo4TSo1GCn2U1We
```
以下で確認すると、1SOLと表示され、きちんとエアドロップができていることを確認できます。
```
solana balance 7ZsTkwHmm4WutDaoEjf5kyptBqbDzBo4TSo1GCn2U1We
```


SOLはNFTコレクションを作成するためのトランザクション費用として利用します。

## Sugar インストール
[Sugar](https://docs.metaplex.com/developer-tools/sugar/)はCandy Machineをブロックチェーン上に作成するためのCLIツールになります。
これもMetaplexが提供しています。

以下コマンドでSugarをインストールできます。
```
bash <(curl -sSf https://sugar.metaplex.com/install.sh)
```
バージョンが確認できれば成功です。
```
sugar --version
```

## Candy Machineを作成する
Candy Machineを作成するために、まずconfigファイルが必要になります。

configファイルの例です。
```
{
  "price": 0.1,
  "number": 5,
  "symbol": "YC",
  "sellerFeeBasisPoints": 1000,
  "gatekeeper": null,
  "solTreasuryAccount": "6HUmXhXWRX7VJfuSpx788MUZ2EFRSFM2uxX5yF6yhW6r",
  "splTokenAccount": null,
  "splToken": null,
  "goLiveDate": "2023-01-28T15:00:00.000Z",
  "endSettings": null,
  "whitelistMintSettings": null,
  "hiddenSettings": null,
  "uploadMethod": "bundlr",
  "shdwStorageAccount": null,
  "retainAuthority": true,
  "isMutable": true,
  "creators": [
    {
      "address": "6HUmXhXWRX7VJfuSpx788MUZ2EFRSFM2uxX5yF6yhW6r",
      "share": 100
    }
  ]
}
```

各項目の説明は以下に記載があります。
[Configuration | Metaplex Docs](https://docs.metaplex.com/developer-tools/sugar/guides/configuration)

今回のconfigファイルの内容をざっくりと説明すると、以下のような形になります。
* NFT総数: 5
* NFTコレクションのシンボル: YC
* 値段: 0.1SOL
* 売り上げ送付先アドレス: 6HUmXhXWRX7VJfuSpx788MUZ2EFRSFM2uxX5yF6yhW6r
* ミント開始時刻: 2023-1-29 15:00 UTC
* 2次流通手数料: 10%
* クリエイターアドレス: 6HUmXhXWRX7VJfuSpx788MUZ2EFRSFM2uxX5yF6yhW6r

assetsとconfigファイルが格納されているディレクトリ内で
Candy Machineを作成します。
```
sugar launch -c config.json assets
```
途中で
```
Do you want to continue without automatically setting the candy machine collection? (y/n)
```
と聞かれますが、yで大丈夫です。

以下メッセージが表示されたらOKです。
```
[1/2] 🍬 Creating candy machine
Candy machine ID: oBfU65CacdQ6PERbwtEhAbLma8yZbGTfxH19SKzhr7o
~~省略~~
Verification successful. You're good to go!
```

今回はアドレスがoBfU65CacdQ6PERbwtEhAbLma8yZbGTfxH19SKzhr7oのCandy Machineが作成されました。

## Phantom インストール
ミントページでNFTをミントするためには、ブラウザにウォレット拡張機能をインストールする必要があります。
SolanaではPhantomが最もポピュラーなので、Phantomを使います。
以下からお使いのブラウザにPhantomをインストールします。
[Phantom - A friendly Solana wallet built for DeFi & NFTs](https://phantom.app/)

作成したウォレットをPhantomにインポートするために、以下コマンドでmy-keypair.jsonの内容を出力します。改めてですが、出力された内容は他人に知られてはいけない内容です。
```
cat ./my-keypair.json
```

Phantom > Settings > Add / Connect Wallet > Import private key
を選択し、出力されたプライベートキーを入力したら、ウォレットをimportできます。
![2D09E432-85D4-4D9E-ADBF-62A592352316.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626975/e36a0988-8a15-8f25-baa5-d395db8060a6.png)
ただ、importされた直後はMainnet Betaに接続されている状態なので、
Phantom > Settings > Developer Settings > Devnet
を選択して、Devnetに接続します。
![772547EE-513B-4347-A7C1-5D059F19610F.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626975/83b8b58b-c952-18a9-8062-d2b4ac8ea460.png)
Devnetの残高が確認できたらOKです。
![A269DAD4-AACB-49D8-BDCA-5EBB2CD2893F.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626975/d35bc27e-ccfb-f26a-9aa1-7e6d03fec09e.png)


## ミントページの作成
ミントページもMetaplexがOSSとして公開してくれています。
[GitHub - metaplex-foundation/candy-machine-ui: Reference minting UI implementation for the Metaplex Candy Machine Program](https://github.com/metaplex-foundation/candy-machine-ui)

レポジトリをクローンしてきます。
```
git clone https://github.com/metaplex-foundation/candy-machine-ui.git
```

ディレクトリを移動し、モジュールをインストール
```
cd candy-machine-ui
yarn install
```

envファイルを用意
```
cp .env.example .env
```

Candy Machineアドレスを設定
```
vi .env

REACT_APP_CANDY_MACHINE_IDを置換する

REACT_APP_CANDY_MACHINE_ID= oBfU65CacdQ6PERbwtEhAbLma8yZbGTfxH19SKzhr7o

REACT_APP_SOLANA_NETWORK=devnet
REACT_APP_SOLANA_RPC_HOST=https://metaplex.devnet.rpcpool.com/
SKIP_PREFLIGHT_CHECK=true
```

ミントページ起動
```
yarn start
```

起動完了したら、localhost:3000でアクセスできます。
![35E01868-3B78-411E-AC1D-AD95D07113C3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626975/7967a670-8bb9-7bcc-3f56-5fa09d1d211a.png)
Phantom接続
![E993D089-500A-40E0-8E49-FFFD2DE80C63.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626975/c8117941-30b3-ad43-42e2-1fc9e1040caa.png)
接続したらMintボタンが表示されます。
![73D2AEFF-43E8-4841-A5BE-1EA5F661CE74.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626975/e5404944-dddf-a4c2-20e7-6c9344cf51cd.png)
Mintボタンを押したら、Phantomの認証ボタンが表示されるので、認証します。
![7B7AA2C1-A8FF-4F97-A1DF-DC42825BE87E.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626975/30cab928-4d0b-f802-ce54-48bf52129c8e.png)
Mintが成功したら、PhantomからミントされたNFTを確認できます。
![D750AA71-D919-4437-93C0-22620FBC3C52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626975/641e8be3-9b93-3758-b32a-59500314b97b.png)
Solscanでミントトランザクションを確認できます。
https://solscan.io/tx/2S1RcytLGw7bvpM2ET9rNuikzaFS86Tc5MzYCYdsggtZwTdn3m9NEsviAwnpQFPBCLodiXTCAMxVUtJ2Xb9aLyCT?cluster=devnet

## 最後に
以上、SolanaでNFTコレクションを作成して、ミントページでミントするまでをやってみました。
今回は極シンプルな構成でしたが、実際にNFTコレクションをローンチするとなると、ミントフェーズを分けたり、ホワイトリスト設定をしたりということが必要になってきます。
ここについては、時間があれば別記事で解説したいと思います。