【Solana】Generative NFT を売る②【Mainnetで検証】

## はじめに
見切り発車で Generative NFTを売る企画、ぐだぐだの第二回です。
（2021/12/19 : ちなみに、予定していた第三回は延期中です：記事の末尾に追記）
（2021/12/29 : SolSea申請再度リジェクトされました...：記事の末尾に追記）
（2022/04/08 : OpenSeaがまさかのSolana対応！：記事の末尾に追記）

[前回](https://qiita.com/hakumai-iida/items/4d6e70d581d344328b99)、なんとなくSolanaで売ろうと思い立ちました。
で、Solanaに関して色々調べてみたのですが、Ethereumと全然ちがっていて、すごく驚きました。

なんと、スマートコントラクトを自前で作らなくても簡単にコレクションが作成できるようです！
というわけで今回は、Solanaの Mainnet(Beta)で コレクションを作成する手順と検証結果について書いていきます。

## まずは devnetでお勉強
とは言ったものの、いきなり Mainnet(Beta)に突貫するのはさすがになので、まずは、devnetで勉強しましょう。

とくに、下記のサイトが「ここみてください、以上、終了！」っていうぐらい素晴らしくまとまっているのでオススメです。
[https://hackmd.io/@hnbl/hector](https://hackmd.io/@hnbl/hector)

基本的には、devnetでも、Mainnet(Beta)でも手順はかわりません。
が、接続先の設定等で、微妙に違うところもありますので、その差に注意しつつ以下をお読みください。

## SolanaにおけるNFTの作成
冒頭でも少し書きましたが、SolanaのNFTの作り方は、Ethereumとはだいぶ異なり、スマートコントラクトを作成する必要がありません。
NFTに対応するスマートコントラクトはあらかじめ、Solanaのブロックチェーン上に存在しており、そのコントラクトへ作りたいNFTの情報を送るだけで、あとはよろしくやってくれるようです。

手順としては大まかに下記のステップとなります。
1. Solanaアカウントの準備
2. メタデータのアップロード
3. コレクション（キャンディーマシン）の作成
4. MINTページの生成

さて、NFTのもととなる画像やメタデータに関しては、Solanaでも Ethereumとやることは同じです。
大量の画像やメタデータの生成に関しては、先にあげた[参考サイト](https://hackmd.io/@hnbl/hector)に、いくつかやり方が載っています。

とりあえず、今回の検証では NFT 20+10個分の素材を用意しました。
Solseaへの申請ついでに、素材をグーグルドライブに上げてありますので、下記でご覧いただけます。
[素材① 20個分](https://drive.google.com/drive/folders/1VBiGG_7fki6gmT5EWK6ATod9SH1917hW?usp=sharing)
[素材② 10個分](https://drive.google.com/drive/folders/1jv80hboCZIG5GiO2gxJ7PtuOIHSZIgpL?usp=sharing)
段ボールと女の子をバラバラに組み合わせて「シュレーディンガーの猫」と言い張ることにしました（生成の仕組みは[こちらの記事](https://qiita.com/hakumai-iida/items/22c4369677d5e0ea0261)を参照ください）。

では、手順の紹介をしていきます。
以降の内容は、mac環境での説明となりますが、Linux、Windowsでも基本は同じだと思います。
ツールのインストールや細々としたフォルダの操作等は、お使いのOSに合わせて適宜読み替えてください。

## Solanaアカウントの準備
Generative NFTを作る際は、コレクションごとに、管理用のアカウントを作っておくと便利です。
ここでは、アカウント作成に必要なコマンドをインストールし、アカウントを作成し、NFTの作成で必要になるガス代を転送します。

### Nodeの準備
以降の処理では、**node**(厳密には **ts-node**)を使うのでバージョンを確認しておきましょう。

```
$ node --version
v16.13.1
```

もし、**node**が未インストールの方は下記のページ等を参考にインストールしてください。
[https://www.sejuku.net/blog/72545](https://www.sejuku.net/blog/72545)

また、以降の処理で、**node**のバージョンでエラーがでた場合は、下記のページ等を参考にバージョンアップしてください。
[https://parashuto.com/rriver/tools/updating-node-js-and-npm](https://parashuto.com/rriver/tools/updating-node-js-and-npm)

### Solanaアカウントの作成と設定
**solana**(CLI)にてコレクション管理用のアカウントを作成します。
ここで作成するアカウントが、今回作成するコレクションのオーナー(メタデータの作成者)となります。

まずは、**solana**(CLI)をインストールします。

```
$ sh -c "$(curl -sSfL https://release.solana.com/v1.8.0/install)"
```

インストールが終わったら、バージョンを確認しておきましょう。

```
$ solana --version
solana-cli 1.8.0 (src:4a8ff62a; feat:1813598585)
```

つづいて、アカウントを作成します。

```
$ solana-keygen new --outfile ~/.config/solana/collection.json
```

コマンドを実行すると、追加でパスワードの設定が必要です（確認の入力があるので２回入力します）。
作成が完了すると、下記のようにニーモニック(12個の秘密の単語)が表示されるので忘れずにコピーしておきます。

```
Wrote new keypair to /Users/hakumai/.config/solana/collection.json
==========================================================================
pubkey: GwhCZZ5NG1F7gT1pEdWoknmdwYvh3UR81rDV8aeaK1WQ
==========================================================================
Save this seed phrase and your BIP39 passphrase to recover your new keypair:
???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ????
==========================================================================
```

Solanaのファイルウォレットはデフォルトで、**~/.config/solana**で管理されるようなので、このサンプルでもそこに出力しています。
また、Phantomにアカウントをインポートする際は、ここで作成した jsonファイルの内容を「秘密鍵」のところに貼り付けることで行います。

アカウントの作成が済んだので、接続先をメインネットへ切り替えます。

```
$ solana config set --url mainnet-beta
```

また、コンフィグの参照するアカウントを、さきほど作成したアカウント(キーペア)へ切り替えておきます。

```
$ solana config set --keypair ~/.config/solana/collection.json
```

最後に、コンフィグの確認をします。

```
$ solana config get
Config File: /Users/hakumai/.config/solana/cli/config.yml
RPC URL: https://api.mainnet-beta.solana.com 
WebSocket URL: wss://api.mainnet-beta.solana.com/ (computed)
Keypair Path: /Users/hakumai/.config/solana/collection.json 
Commitment: confirmed 
```

これで、以降の **solana**(CLI)の実行は、Mainnet(Beta)へ向けて **collection.json**アカウントで行われるようになりました。


### ガス代(SOL)の準備
管理アカウントができたので、SOLを送金しておきましょう（取引所、DeFi等、なんらかのやり方で入手してください）。

送金したら残高を確認します。

```
$ solana balance
1 SOL
```

ちなみに、devnet、testnetの場合は、下記のようにエアドロップでテストSOLを増やすことができます。

```
$ solana airdrop 1
```

## MetaPlexでメタデータのアップロード
メタデータのアップロードには、MetaPlexを利用します。

### MetaPlexのインストール
MetaPlexをインストールするフォルダへ移動して、**git**でリポジトリをチェックアウトします（この例ではホームにチェックアウトしています）。

```
$ cd ~
$ git clone https://github.com/metaplex-foundation/metaplex.git
```

MetaPlex内の **js**フォルダに移動して **yarn install** により必要なモジュールのインストールします。

```
$ cd ~/metaplex/js
$ yarn install
```

もし、**yarn** がインストールされていない場合は、下記のサイト等を参考にインストールしてください。
[https://qiita.com/suisui654/items/1b89446e03991c7c2c3d](https://qiita.com/suisui654/items/1b89446e03991c7c2c3d)

インストール後は **cli**フォルダに移動して、**yarn build**を実行します。

```
$ cd ~/metaplex/js/packages/cli
$ yarn build
```

ビルドが正常終了したら、MetaPlexの準備は完了です。

注意点として、2021/12/12現在、MetaPlexは頻繁に更新されているようです。
動作が安定しない場合は、最新よりも少し古めのリビジョンを取得すると動くかもしれません。

ちなみに、今回の例で取得した MetaPlexは下記のリビジョンとなります。

```
$ git rev-parse master
c3a9024c928c4658cb32161a34ce585f8279441a
```

### 作業フォルダの準備と素材の配置
この例では、**~/myFirstCollection**を作成して作業フォルダとします。

```
$ cd ~
$ mkdir myFirstCollection
$ cd ~/myFirstCollection
```

そして、上記作業フォルダに **assets**というフォルダを作成し、メタデータとなる jsonと、 pngを配置します。
この時、jsonと pngの名前は、０初めの連番にしないといけません（詳しくは、先にあげた[参考サイト](https://hackmd.io/@hnbl/hector)を参照ください）。

例えば、20個のNFTを作成する場合は下記のように配置します。

```
$ ls ~/myFirstCollection/assets
0.json	1.json	10.json	11.json	12.json	13.json	14.json	15.json	16.json	17.json	18.json	19.json	2.json	3.json	4.json	5.json	6.json	7.json	8.json	9.json
0.png	1.png	10.png	11.png	12.png	13.png	14.png	15.png	16.png	17.png	18.png	19.png	2.png	3.png	4.png	5.png	6.png	7.png	8.png	9.png
```

さて、このサンプルでは、レア扱いの　NFTにはムービー(MP4)をわりあてることにしました。
ですが、MetaPlexでアップロードできるのは、メタデータとなる　jsonに紐づいた　pngのみのようです。

このため、MP4ファイルはあらかじめ、IPFSへアップロードしておき、jsonの animation_urlに IPFSへのパスを記入しておきました。
この時、パスの最後にファイルの種類を指定するための **?ext=mp4**をつけることを忘れないでください。これがないと Phantom等で正常に表示されないようです。
さらに、プロトコルとして **ipfs://** を指定すると表示されないようなので、**https://**ではじまるゲートウェイでパスを指定する必要があるようです。

上記を踏まえ、mp4つきのメタデータは下記のようになりました。

``` json
{
  "name": "DoAC #1",
  "symbol": "DoAC",
  "description": "Dead or Alive Cats #1",
  "seller_fee_basis_points": 500,

  "image": "0.png",
  "animation_url":"https://ipfs.infura.io/ipfs/QmV4MBv6wfSREYBYUX5NrZRb5usTQRwk9rbnmH9tTPPZBw/DoAC_a01.mp4?ext=mp4",

  "attributes":
  [
    {
      "trait_type": "Rarity",
      "value": "Rare"
    },
    {
      "trait_type": "Status",
      "value": "Alive"
    }
  ],

  "collection": {
     "name": "DoAC 1st Alive Collection",
     "family": "DoAC"
  },

  "properties": {
    "files": [
      {
        "uri": "0.png",
        "type": "image/png"
      },
      {
        "uri": "https://ipfs.infura.io/ipfs/QmV4MBv6wfSREYBYUX5NrZRb5usTQRwk9rbnmH9tTPPZBw/DoAC_a01.mp4?ext=mp4",
        "type": "video/mp4"
      }
    ],
    "category": "video",
    "creators": [
      {
        "address": "4dgfHoJ3v2HvbY94eQz3n1DbohyUxxPtivbZmeFeHoZX",
        "share": 100 
      }
    ]
  }
}
```

また、mp4を含まない普通のpngの場合、jsonは下記のようになりました。

``` json
{
  "name": "DoAC #6",
  "symbol": "DoAC",
  "description": "Dead or Alive Cats #6",
  "seller_fee_basis_points": 500,

  "image": "5.png",

  "attributes":
  [
    {
      "trait_type": "Rarity",
      "value": "Normal"
    },
    {
      "trait_type": "Status",
      "value": "Alive"
    }
  ],

  "collection": {
     "name": "DoAC 1st Alive Collection",
     "family": "DoAC"
  },

  "properties": {
    "files": [
      {
        "uri": "5.png",
        "type": "image/png"
      }
    ],
    "category": "image",
    "creators": [
      {
        "address": "4dgfHoJ3v2HvbY94eQz3n1DbohyUxxPtivbZmeFeHoZX",
        "share": 100 
      }
    ]
  }
}
```

上記のメタデータ内で、**0.png**、**5.png**として指定される画像が、MetaPlexによりアップロードされ、実際の URLに置換される作りのようです。

### メタデータのアップロード
さていよいよメタデータのアップロードです。
ここからの手順は Solanaブロックチェーンへの書き込みが必要なため、トランザクションを発行するアカウント(keypair)の秘密鍵が必要です。

では、**assets**と同じ階層へ移動して、メタデータのアップロードを開始しましょう。

```
$ cd ~/myFirstCollection
$ npx ts-node ~/metaplex/js/packages/cli/src/candy-machine-cli.ts upload ./assets --env mainnet-beta --keypair ~/.config/solana/collection.json
```

この時、**ts-node**がインストールされていない場合、下記のように表示されるので '**y**'を入力してインストールします。

```
Need to install the following packages:
  ts-node
Ok to proceed? (y) 
```

また、本番環境ではたまにエラーが発生するようです（下記のエラーはタイムアウト）。

```
upload was not successful, please re-run. Error: Transaction was not confirmed in 30.01 seconds. It is unknown if it succeeded or failed. Check signature 5EwKJGpRX83tYz1ZqSmHLxjV9cgJcPZvp3GEH7CofyV5fvSFbs8KqV28A5gCvwgMoA7x22v1b12ENUpJriekmSEg using the Solana Explorer or CLI tools.
```

もしエラーがでた場合は、慌てず騒がず内容を確認し、諦めずに、何度かリトライしてみましょう。
jsonと pngに問題がなければ、いずれアップロードが完了して、下記のようなログが表示されまず。

```
wallet public key: GwhCZZ5NG1F7gT1pEdWoknmdwYvh3UR81rDV8aeaK1WQ
Saved bundle upload result to cache.
Computed Bundle range, including 20 file pair(s) totaling 10.519MB.
Uploading bundle... in multiple transactions
0.000705733 SOL to upload
Bundle uploaded!
Saved bundle upload result to cache.
Upload done.
Initializing program config
Initialized config for a candy machine with publickey: Amt79QUhPw4sTaKHJUB1P5AedBvgaqAsvHPBhDZjshdU
Writing indices 0-9
Writing indices 10-19
ended at: 2021-12-12T00:44:44.560Z. time taken: 00:02:06
```

で、完了時に表示される、「**Initialized config for a candy machine with publickey:**」の値はあとで使うので忘れずに控えておきましょう。
（もし控え忘れた場合は、**assets**と同じフォルダにできる **.cache/.mainnet-beta-temp.json**の中の **config**値を見直しましょう)

アップロード後は、下記のコマンドで内容をベリファイできます（出力された **.cache**フォルダと同じ階層で実行します）。

```
$ npx ts-node ~/metaplex/js/packages/cli/src/candy-machine-cli.ts verify --env mainnet-beta --keypair ~/.config/solana/collection.json
```

ベリファイに問題がなければ下記のような出力になるはずです（結構時間がかかるので注意してください）。

```
wallet public key: GwhCZZ5NG1F7gT1pEdWoknmdwYvh3UR81rDV8aeaK1WQ
Name DoAC #1 with https://arweave.net/MmAFnOkyTzTbrQoKasUZQTONWzlbc1NxhxVN53-D6C0 checked out
Name DoAC #2 with https://arweave.net/6J1myZRSgYVOcphuS8q13_ct2kON0Sn_i8QXjoqTG7E checked out
 (省略)
Name DoAC #19 with https://arweave.net/JYAS61RdXh_BMus7_2IS9SchOaPNqgQZgHL5VetovIo checked out
Name DoAC #20 with https://arweave.net/TvW9FaBwHXC96YXoIiui2PxsHvrGVp3n5Dn7OQDvbSo checked out
uploaded (20) out of (20)
ready to deploy!
```

これで、メタデータのアップロードは完了です。
つづいて、キャンディマシーンの作成を行いましょう。

## キャンディーマシン（コレクション)の作成
アップロードしたメタデータを NFTとして MINTできるようにしてくれるのがキャンディマシーンです。
アメリカの英語とかにでてくる、あのキャンディのガチャガチャのことですね！

まず、MINTに必要な価格を **--price** で指定して、キャンディマシーンを作成します。

```
$ npx ts-node ~/metaplex/js/packages/cli/src/candy-machine-cli.ts create_candy_machine --env mainnet-beta --price 0.001 --keypair ~/.config/solana/collection.json
```

作成が完了すると、下記のように表示されます。

```
wallet public key: GwhCZZ5NG1F7gT1pEdWoknmdwYvh3UR81rDV8aeaK1WQ
create_candy_machine finished. candy machine pubkey: BB3KVWvXri811sXScsTnkybqZ9p59KWGjTCujWvKidbF
```

ここで出力される、「**create_candy_machine finished. candy machine pubkey:**」の値は後で使うので忘れずに控えておきましょう

つづいて、作成したキャンディマシーンの販売開始時刻を設定します。
この時、販売開始の設定：時間の指定は 「**日 月 年 時:分:秒 PST**」の文字列で指定しないとダメなようです。
（試しに、PSTの部分をJSTにしたらうまく動かなかったので注意してください）

```
$ npx ts-node ~/metaplex/js/packages/cli/src/candy-machine-cli.ts update_candy_machine --env mainnet-beta --keypair ~/.config/solana/collection.json --date '12 Dec 2021 00:00:00 PST'
```

設定が成功すると下記のように表示されます。

```
wallet public key: GwhCZZ5NG1F7gT1pEdWoknmdwYvh3UR81rDV8aeaK1WQ
 - updated startDate timestamp: 1639296000 (12 Dec 2021 00:00:00 PST)
update_candy_machine finished fsHomPFjwFduPyh5orgFKwiiUkUjfTXnjfQhjevzQXuDYZLUChW924ZTpwHmjDwxdGAaJZEEMbbjK5gRqpe4sXG
```

ここで表示される、「**- updated startDate timestamp:**」もあとで使用するので忘れずに控えておきましょう。

これで、Solanaブロックチェーン上において、NFT(アップロードしたメタデータ)が MINT可能な状態になりました。
あとは、MINTページを生成するだけです。

## MINTページの生成
Solanaではキャンディマシーンに対応する MINTページ(**index.html**や **Web3.js**関連の処理)を自動で作ってくれます。

まずは、MINTページを作ってくれるツールをチェックアウトしましょう。
（MINTページはコレクションごとに作成することになるので、**assets**と同じ階層にチェックアウトしています）。

```
$ cd ~/myFirstCollection
$ git clone https://github.com/exiled-apes/candy-machine-mint.git
```

チェックアウト後は、フォルダのなかに入って、モジュール等のインストールをします。

```
$ cd ~/myFirstCollection/candy-machine-mint
$ yarn install
```

### .env の作成
MINTページの内容を設定するのが **.env**ファイルとなります。
フォルダの直下にもととなるテンプレートがあるのでコピーします。

```
$ cp .env.example .env
```

つぎに、**.env**をテキストエディタで開いて、作成したキャンディマシーンの情報等を設定します（ここでは Mainnet(Beta)へ接続するということをお忘れなく！）。

```
REACT_APP_CANDY_MACHINE_CONFIG=メタデータアップロード時の「Initialized config for a candy machine with publickey:」の値
REACT_APP_CANDY_MACHINE_ID=キャンディマシーン作成時の「create_candy_machine finished. candy machine pubkey:」の値
REACT_APP_TREASURY_ADDRESS=キャンディマシーンの作成アカウント（この例だと[collection.json]の公開鍵）
REACT_APP_CANDY_START_DATE=キャンディマシーンの販売期間設定時のタイムスタンプの値

REACT_APP_SOLANA_NETWORK=mainnet-beta
REACT_APP_SOLANA_RPC_HOST=https://explorer-api.devnet.solana.com
```

今回の例では下記のようになりました。

```
REACT_APP_CANDY_MACHINE_CONFIG=Amt79QUhPw4sTaKHJUB1P5AedBvgaqAsvHPBhDZjshdU
REACT_APP_CANDY_MACHINE_ID=BB3KVWvXri811sXScsTnkybqZ9p59KWGjTCujWvKidbF
REACT_APP_TREASURY_ADDRESS=GwhCZZ5NG1F7gT1pEdWoknmdwYvh3UR81rDV8aeaK1WQ
REACT_APP_CANDY_START_DATE=1639296000

REACT_APP_SOLANA_NETWORK=mainnet-beta
REACT_APP_SOLANA_RPC_HOST=https://explorer-api.mainnet-beta.solana.com
```

### MINTページの確認
**.env**の設定おわったら、いよいよ MINTページの確認です。

```
$ yarn start
```

上記のコマンドを実行すると、Chromeが起動して、NFTの発行数等の情報と、MINTボタンが表示されます。
![ss00_yarn_start](https://user-images.githubusercontent.com/13220051/145706617-b55f9a09-b2a8-4993-b7a3-c48e90c63419.png)
この画面が表示されればMINTの設定は完了です。
もし、**.env**の設定に問題がある場合はエラーが表示されるので、内容をよく確認して修正しましょう。

MINTページの内容に問題がなければ、最後は MINTページのビルドです。

```
$ yarn build
```

これで、**static**フォルダに、**index.html**や関連する JavaScript等のファイルが出力されます。
あとは、この内容をもとにしてデザインを組み込むことで、Generative NFTの販売サイトとして完成です！

ちなみに、ここまでに消費したガス代は下記となりました。
作業前: 1.0 SOL
作業後: 0.9571733 SOL
ガス代: 0.0428267SOL
約 820円、お安い！

## さらに検証
さて、NFTを売るまでの手順はこれにて完了なのですが、Solana上の NFTに関して色々とわからないことが多いので検証してみました。

### NFTの MINT代
まず、本番環境での MINT代の実測として、キャンディマシーンに登録した 20個の NFTを全て、管理アカウントで MINTしてみました。
NFTの価格(0.001 SOL)は MINするアカウントへそのまま入るので、 MINT前後の SOLの差分が純粋にガス代となる計算です。

MINT前: 0.9571733 SOL
MINT後: 0.7175493 SOL
ガス代: 0.2396240 SOL
約 4600円、以外と高いですね。

NFT一個あたりの値段は、約 230円という感じでしょうか？
NFTの販売準備までにかかったガス代と比べてかなり高く感じられますが、これはなぜでしょう？

[https://solscan.io/address/68gNWd85JvMZWn5s7xaP2YBV1yfwP89htZNbB1bxnses](https://solscan.io/address/68gNWd85JvMZWn5s7xaP2YBV1yfwP89htZNbB1bxnses)

実際に、NFTにひもづいたアカウントを見てみると、 0.00203928 SOL(約40円) の残高があります。
これがいわゆる、Solanaのアカウント(ストレージ等)の家賃というやでしょうか？

Solanaでは、NFTの発行のなかで作成される各種アカウントが、ブロックチェーン上のストレージを占有しつづけるには SOLが必要なのだそうです。
で、アカウントからは刻々と SOLが引き落とされるのだそうですが、ある程度の SOLをあらかじめ振り込んでおくと、この家賃が免除されるのだそうです。
この家賃の振り込みで、ガス代が高くなっているのではないかと思います。

### NFTの見え方
発行したNFTのうち、MP4をひもづけたものも、Phantom上で正常に表示されました。
![ss03_phantom_detail](https://user-images.githubusercontent.com/13220051/145706620-0247f07a-0f4e-4021-ae45-2577c2a87a76.png)

また、Solscan上でも、MP4の表示に問題はありませんでした。
[https://solscan.io/token/7qgMLGmvU3ZapZQPJJEVMMs4FNkfdeg3oZbGzdwvsRPh](https://solscan.io/token/7qgMLGmvU3ZapZQPJJEVMMs4FNkfdeg3oZbGzdwvsRPh)

### 同一コレクションへのNFTの追加発行はできない？
例えば、あるコレクションとして NFTを 1000個作成したとします。
で、このコレクションが完売したら、さらに追加で 1000個追加したいというケースは可能なのでしょうか？

この検証用に、もう一つ、キャンディマシーンを作ってみました。
（説明の都合上、先に作ったのを**Ａ**、次に作ったのを**Ｂ**とします）

で、キャンディマシーン**Ｂ**に投入したメタデータは下記のようになります　。

まず、symbolは**Ａ**と同じにしてみました。

```
　"symbol": "DoAC",
```

次に、**collection**要素の、**name**を別にして、**family**を同じにしてみました。
結果として、コレクション**Ａ**の設定は下記となり、

```
　  "collection": {
     "name": "DoAC 1st Alive Collection",
     "family": "DoAC"
  },
```

コレクション**Ｂ**の設定は下記となりました。

```
　  "collection": {
     "name": "DoAC 1st Dead Collection",
     "family": "DoAC"
  },
```

これらの設定でキャンディマシーン**Ｂ**をつくり、早速、10個 MINTし、Phantomで見てみました。
![ss05_additional_nft](https://user-images.githubusercontent.com/13220051/145706623-1a76f984-452b-4d6b-8bca-3c5aa68528fa.png)

うーん、Phantom上では別々に取り扱われてしまいました。
**family**の設定を同じにした場合、同じコレクションとして表示されることを期待していたのですが違ったようです。
でも、よく考えたら、**family**設定を同じにするだけで、他者の作ったコレクションに紛れ込めてしまうのはマズイですし、これは仕様として正常なのでしょうね。

## マーケットへの登録
さて、検証用とはいえコレクションができたわけなので、マーケットの下調べもしておきましょう。

### Solanart
[https://solanart.io/](https://solanart.io/)

[登録フォーム](https://forms.gle/owdArnDRwZL6Sbnk7)があるのでそこから申請します。
申請はグーグルアカウントに紐づいており、１アカウントで１つの申請しか受け付けてくれないようです。
詳しくは[ヘルプ](https://solanart.io/faq)内の「How do I mint/list my own collection on Solanart?」を参照ください。

### Alpha Art
[https://alpha.art/](https://alpha.art/)

ウォレット接続後、右上の設定ボタン（丸に点が３つならんだアイコン）から[**Submit Collection**]を選択して申請します。
申請は Solanaアカウントに紐づいており、１つのコレクションに複数のキャンディマシーンのIDを登録できるようです。

### Solsea
[https://solsea.io/](https://solsea.io/)

申請だけでなく、サイト上で NFTやコレクションの作成等ができるようです。
コレクションの申請手順としては Solsea上で作成したコレクションページに、外部で作成したコレクション(キャンディーマシーンのID)を紐づける感じのようです。
詳しくは[FAQ](https://docs.solsea.io/getting-started/faq)の「[Can I mint my collection externally and have my collection listed on SolSea?](https://docs.solsea.io/getting-started/faq/collections-create-edit-verify#can-i-mint-my-collection-externally-and-have-my-collection-listed-on-solsea)」を参照ください。

### Magic Eden
[https://magiceden.io/](https://magiceden.io/)

画面上部のメニューから「適用」を選び、そこある「APPLY FOR LISTING」から申請をします。

以上、
４つのサイトを見比べてみましたが、コレクション(プロジェクト)専用のdiscordチャンネルが必要だったりするサイトが多く、個人レベルだとなかなかハードルが高い印象をうけました。
その中で、Solseaの申請が提出物は多いものの、単純なNFTのコレクションとして登録してくれそうなため、ハードルが低そうな印象でした。

## おわりに
いやはや、Solanaは便利ですね。

Ethereumでスマコンを書くハードルの高さと比べると、キャンディマシーンのクリエイターフレンドリーさには脱帽です。
もちろん、初めて操作する場合は色々と迷う部分もあるわけですが、それでも、参考サイトをみながらなんとなくコレクションが作れてしまうのは隔世の感があります。

さて一方、[１回目](https://qiita.com/hakumai-iida/items/4d6e70d581d344328b99)にアイデア勝負の NFTを作る、などと息巻いていましたが、特にアイデアはまとまりませんでした。
現状、Solanaのマーケットで動画の NFTをあまり見かけないので、動画の NFTを大量生産したら、少しはめだつのではないかなどと思っています。

~~では、第３回でお会いしましょう。~~

## 追記 2021/12/19
第三回で大団円と思っていました（いや本当は思っていませんでした）が、マーケット申請が一つも承認されなかったので、続きの記事はある程度情報がたまってからにしようと思います。

ちなみに、１週間経った段階での、各マーケットへの申請状況は下記となります。

・[Solanart](https://solanart.io/)
**音沙汰ありません**
まぁ、ハードルが高そうなんで予想はしていました。
あわよくば、「この条件に達していないので却下です」というような判断基準なんかが返って来るかなと思っていましたが、それすらなく...。

・[Alpha Art](https://alpha.art/)
**こちらも音沙汰なし**
Solanartよりはハードルが低そうな印象（入力項目は不足なく埋められたはず）だったんですが、こちらもなんの返事も来ていません...。

・[Magic Eden](https://magiceden.io/)
**そもそも申請すらしていなかった**
Discordの招待リンクとか、なかなかハードルが高そうだったんで、申請すらしてません...。

・[Solsea](https://solsea.io/)
**唯一反応あり**
とはいえ、メール等で通知がくるのではなく、自分でサイトの申請ステータスを確認しにいかないと状況は分かりませんでした（ステータスが変わるまで４日ぐらいかかりました）。
ちなみに、内容は「情報の不備による却下」でした。

>The verification of your collection has been declined.
>
>Please provide us with a screen recording depicting the work process of art making from the ground up. That includes any art templates you >might have used in the creation process. Thank you in advance!

どうやら、アーティスト（画像の作成者）の証明のために提出した素材が不足していたようです。
NFTの元素材をおくったのですが、それだけでは足りなかったようで、制作過程の情報もくれとのこと。

私の素材作成環境は、Xcodeで作成した自作ツール（元はゲーム向け）なので、その操作の流れを録画して再申請してみました。

[制作過程①](https://drive.google.com/drive/folders/18jDOQ4s9n6cvnkermDZJw2cnqQVXZ5Tp?usp=sharing)
[制作過程②](https://drive.google.com/drive/folders/1GWtt7sr-Ux9v9IQP4aV_hHg8D0D1Ej6H?usp=sharing)

こんな情報でよいのか不安ですが、現在、再申請待ち中となります（再申請後、２日経過した時点ではステータスに変化なし）。
結果がでたら、追記したいと思います。

しかしながら、Solanaは NFTの一次販売までがとても手軽な一方で、二次販売となるマーケットへの登録が予想以上に大変そうです。こちらの意味でも、OpenSeaとは対照的ですね（あちらは MINTしたら勝手に登録され、コレクションページの編集も即反映される）。

## 追記 2021/12/29
[Solsea](https://solsea.io/)の再申請もリジェクトされてしまいました...。

>We have noticed that you have some pieces that we like listed on another blockchain.
>We would be interested in verifying those pieces on our platform,
>but in order to do that they would first need to be delisted from the other blockchain.
>Think about it and get back to us. Hoping to hear from you soon !

なにやら別のチェーンで似たような NFTを販売しているとダメなようです。

たしかに、私は [OpenSeaで似たようなNFTを販売](https://opensea.io/collection/four-character-idiomatic-compounds)しています（というか売れ残っているというのが正解です...）。
ですが、NFTのコンセプトは違いますし、同じ作成者なので絵的に似てしまうのはしかたがないと思うのですが、受け入れてもらえないようです。

そして最大の問題が、OpenSeaで販売を停止する場合、今だと１NFTにつき **$20** ぐらいのガス代がかかってしまうということ。
これは経済的に無理なので、今回の申請は諦めるしかなさそうです。

それにしても、Solseaで NFTを売ろうと思ったら、すでにOpenSeaとかで売っているNFTとは完全に別物の、オリジナルだと主張できるぐらいのものを作らないといけないとは...。

## 追記 2022/04/08
なんと、OpenSeaがSolanaに対応しました！
[https://opensea.io/explore-solana](https://opensea.io/explore-solana)

現在はベータ版で一部の有名コレクションしか扱っていないようですが、正式リリースではMetaPlexに準拠したコレクションを扱ってくれるみたいです。
ということは、個人レベルで作成したSolanaのNFTが気軽に売れるようになる！？

```
Our initial beta launch will have limited collection coverage.
Full launch will include a scalable way to expand coverage via the Metaplex collection standard, so if you want to prepare, you can adopt the standard now.
```

OpenSeaへ出品しているNFTのせいでSolSeaからリジェクトされた私としては、OpenSeaに救われた気分です。
OpenSeaのSolana正式対応を楽しみに待ちたいところですね。