OpenSeaの様なNFTマーケットプレイスを作ってみた。

![NFTブログ用.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299653/a6314fa3-b209-0a5e-8485-807ad6a129cb.jpeg)


以前、ブログにERC20トークンを独自に作成するアプリについて投稿したので今回は、ERC721（NFT）に関する記事を投稿させていただきたいと思います！

# 概要
 1. 作成したアプリについて
 2. 実装したスマートコントラクトについて
 3. アプリの動きについて
 4. 最後に

## 作成したアプリについて
今回作成したアプリですが、Udemyの下記コースを受講して作成いたしました。  
<a href="https://www.udemy.com/course/the-complete-nft-web-developer-course-zero-to-professional/">The Complete NFT Web Development Course - Zero To Expert</a>

上記のコースでは、NFTの定義の解説に始まり、Solidityの基本的なコーディングルール、React.jsのプロジェクトの作成方法までレクチャーしていただける大変質の良いコンテンツでした！内容は、字幕も含めて全て英語となっておりますが、NFTとSolidity、React.jsについての知識を持っていれば特段問題ないと思われます！
受講後は、修了証明書も発行してもらえるので自分のポートフォリオ用のサイトに貼り付けるなどしてアピールすることもできるのではないでしょうか？

受講が完了すると下記の様に、OpenSeaの様なNFTマーケットプレイスを作成することができます！(OpenSeaに比べるとかなり規模は小さいし、機能も足りないです・・(売買機能とか))

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299653/a8cd9a98-5ab8-cd3b-4a71-46801a6d9c54.png)

## 実装したスマートコントラクトについて
通常であればERC721のスマートコントラクトは、1から作成せずにOpenZeppelin等が用意してくれているライブラリを使うのが一般的だと思うのですが、今回はそれらのライブラリをお手本として扱い、最低限の機能を自分で実装していきました。

実装した機能の内容については大きく分けて下記の通りです。

|No|実装したもの|
|---|---|
|1|ERC721|
|2|ERC165|
|3|SafeMath|
|4|Counters|

1のERC721とそれに付随するスマートコントラクトがメインで、3と4はライブラリになります。

3のSafeMathについては、四則演算の際にオーバーフローなどを防ぐためのチェック機能を実装しています。

メインとなったERC721ですが、今回はapprove関連のメソッドはあまり深く踏み込まずに

発行するためのmintメソッド
第三者にNFTの所有権を移譲するためのtransformメソッド
トークンの存在を確認するexistsメソッド
残高を確認するためのbalanceOfメソッド
NFTの所有者であることを確認するownerOfメソッド

をメインに実装しています。

ERC165についてもようやく意味がなんとなく理解できましたのでメモ程度ですが記載させていただきます。

:::note info
  ERC165はスマートコントラクトがどのインタフェースを実装するかを公開し発見する標準的なメソッドを作成するための規格のこと。
  コントラクトがどんなインターフェースを実装しているのかを確認できるようにするためのインターフェースを定義している。  
  今回は開発したERC721コントラクト用のメソッドのフィンガープリントをkccak256関数を使って生成し、登録している。
:::

## アプリの動きについて

次にアプリの動きについてですが、上記の通り最低限の機能しか実装していないので、NFTを発行してそれを画面上に並べて表示していくというのが大きな機能になります。

① NFTマーケットプレイスを起動させる前に、まずGanacheを起動させます！
![スクリーンショット 2022-05-01 11.45.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299653/679bce08-7a7c-86b3-00a5-2c49cb86f3f2.png)

② そしてこの中のアカウントの秘密鍵をMetaMaskにインポートしておきます！
(この流れについては、前回の投稿で詳しく記載させていただいておりますのでそちらも合わせて確認していただけると幸いです。)

③ 上記が完了したら、npm run startコマンドを打ち込んでReact.jsアプリを立ち上げます！
うまくいけば下記の様な画面が表示されるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299653/a8cd9a98-5ab8-cd3b-4a71-46801a6d9c54.png)

次にNFTを発行することになるのですが、その時は、一番上の入力フォームにNFTと紐づけたいデジタル資産までのURLを貼り付けることになります！！(ここ重要です！！)

:::note info
NFTコントラクト内では、このデジタル資産までのURLとトークンIDを紐付ける形で保持することになります。ここにブロックチェーンの耐改竄性が活きてくるわけですね！
:::

今回は、<a href="https://imgbb.com/">imgbb</a>を利用して、URLを用意しました。

用意ができたら発行しましょう！！

④ URLを入力フォームに入力する。
⑤ mintボタンを押す。
![スクリーンショット 2022-05-01 11.56.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299653/20d4bf56-5b87-f7e6-b934-a5adba185db9.png)

うまくいけば一番下に発行したNFTのデータが反映されます！(我が家の愛犬の写真を利用しました！)
![スクリーンショット 2022-05-01 11.57.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299653/c04ddd96-f9cb-2339-21e2-a62385f826e3.png)

追加されていますね！！
ここまでが大きな流れになります。

## 最後に

今回は、OpenZeppelinのライブラリを用いずにあえて0から実装することでNFTの根本的な部分を理解することができたと思います。

まず、NFTの基本的な機能は所有者であるアドレスとコントラクトから発行したトークンIDを紐付けるに過ぎないということ。
次に、カスタマイズなどでデジタルアートや音楽データなどを紐づけることは可能だが、本体となるデータをブロックチェーン上に保存しておくかそうでないかが重要になってくること。人によっては、Base64でエンコードしてブロックチェーン上に保存しておくという実装もしているようですが、そうでない場合は、今回のようにimgbbなどのサービスを使うことになります。しかし、この場合はブロックチェーン上に登録しておくのはデジタル資産までの住所にあたる情報だけなので、住所先にあるデータそのものが改ざんされてしまった場合はどうしようもありません。この場合には、認証局の様に信頼できる第三者機関に預ける必要が出てくるのではないかと感じました。

2021年にジャック・ドーシー氏の最初のツイートが3億円で入札されたりと色々とバズっているNFTですが、課題もまだまだありそうです。
セキュリティ会社に勤める者としてこのあたりは真剣に考えていきたいと考えています。(機能的にそもそもお金のやり取りにあんまり向いていない気がしてきました。。。 医療分野とか教育の分野に対するポテンシャルはとても高そうですよね！！)

今後の課題としては、今のままでは講師のプロジェクトのただのコピペになってしまうので、発行機能はもちろんのこと、他人にNFTを移転したり償却したりできる機能を追加したアプリを作成することを目標にしたいと思います！

ここまで読んでいただきありがとうございました！