NFTの作り方
著者: Alchemy Team
このチュートリアルでは、EthereumとInter Planetary File System(IPFS)を使ってNon Fungible(ERC721)Tokenのスマートコントラクトを作成し、デプロイする手順を説明します。
このガイドの所要時間:約15分
たとえ世間から隔絶した生活をしていたとしても、主要なニュースメディアがこぞってNFTの台頭を取り上げていることには気づいているはずです。
NFTによってブロックチェーンが一般の注目を集めるようになった今、自分自身でEthereumブロックチェーン上にNFT(ERC-721 Token)を発行することで、この盛り上がりの正体を理解する絶好の機会です!
このチュートリアルでは、Metamask、Solidity、Hardhat、Pinata、Alchemyを使ってSepoliaテストネットワーク上にERC-721スマートコントラクトを作成・デプロイする手順を説明します(これらの用語の意味がまだわからなくても問題ありません。追って説明します)。このチュートリアルのPart IIでは、作成したスマートコントラクトを使ってNFTをミントする方法を、Part IIIではMetamaskでNFTを表示する方法を解説します。
途中で疑問が出てきた場合は、いつでもAlchemyサポートセンターを訪れてください!
ステップ1:Ethereumネットワークに接続する
Ethereumブロックチェーンにリクエストを送る方法は数多くありますが、ここでは最も簡単な方法として、ブロックチェーン開発者向けプラットフォーム兼APIであるAlchemyの無料アカウントを使用します。これにより、自分でノードを立てることなくEthereumチェーンと通信できます。
このチュートリアルでは、スマートコントラクトのデプロイの裏側で何が起きているかを把握するために、Alchemyのモニタリング・分析用開発者ツールも活用します。まだAlchemyアカウントを持っていない場合は、こちらから無料で登録できます。
ステップ2:アプリを作成する(とAPIキーを取得する)
Alchemyアカウントを作成したら、アプリを作成することでAPIキーを発行できます。これにより、Sepoliaテストネットワークへのリクエストが可能になります。テストネットワークについて詳しく知りたい場合は、このガイドを参照してください。
- Alchemyダッシュボードのナビゲーションバーで「Apps」にカーソルを合わせ、「Create App」をクリックして「Create App」ページに移動します

- アプリに名前を付け(今回は「My First NFT!」としました)、簡単な説明を記入し、Environmentで「Staging」を選択し(アプリの管理に使われます)、ネットワークで「Sepolia」を選択します。

- 「Create app」をクリックすれば完了です!アプリが下の表に表示されるはずです。
ステップ3:Ethereumアカウント(アドレス)を作成する
トランザクションを送受信するにはEthereumアカウントが必要です。このチュートリアルでは、Ethereumアカウントアドレスを管理するためのブラウザ上の仮想ウォレットであるMetamaskを使用します。Ethereum上でのトランザクションの仕組みについてさらに理解を深めたい場合は、Ethereum財団によるこのページを確認してください。
Metamaskアカウントはこちらから無料でダウンロード・作成できます。アカウントを作成する際、またはすでにアカウントを持っている場合は、必ずSepoliaテストネットワークに切り替えてください(本物のお金を扱わないようにするためです)。

ステップ4:フォーセットからetherを受け取る
スマートコントラクトをテストネットワークにデプロイするには、偽のEthが必要です。Ethを入手するには、Sepoliaフォーセットにアクセスし、Sepoliaアカウントアドレスを入力してSepolia Ethをリクエストしてください。しばらくするとMetamaskアカウントにEthが届くはずです!
ステップ5:残高を確認する
残高が反映されているかを確認するために、Alchemyのコンポーザーツールを使ってeth_getBalanceリクエストを送ってみましょう。これによりウォレット内のEth残高が返されます。Metamaskアカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが返されるはずです:
{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}
注: この結果はethではなくweiで表示されています。weiはetherの最小単位として使われます。weiからethへの換算は次の通りです:1 eth = 10¹⁸ wei。したがって、0xde0b6b3a7640000を10進数に変換すると10¹⁸となり、これは1 ethに相当します。
これで、偽のお金がすべて手元にあることが確認できました!🤑
ステップ6:プロジェクトを初期化する
まず、プロジェクト用のフォルダを作成する必要があります。コマンドラインを開き、次のように入力してください:
プロジェクトフォルダの中に入ったら、npm initを使ってプロジェクトを初期化します。npmがまだインストールされていない場合は、こちらの手順に従ってください(Node.jsも必要になるので、こちらもダウンロードしてください!)。
インストール時の質問にどう答えても特に問題ありませんが、参考までに私たちが答えた内容は以下の通りです:
package.jsonを承認すれば準備完了です!
ステップ7:Hardhatをダウンロードする
Hardhatは、Ethereumソフトウェアのコンパイル、デプロイ、テスト、デバッグを行うための開発環境です。本番チェーンにデプロイする前に、ローカルでスマートコントラクトやアプリを構築する開発者を支援します。
ターミナルを開き、my-nftプロジェクトフォルダの中にいることを確認した上で、次を実行してください:
インストール手順についての詳細はこちらのページをご覧ください。
ステップ8:Hardhatプロジェクトを作成する
プロジェクトフォルダ内で次を実行してください:
すると、ウェルカムメッセージと実行したい操作を選択するオプションが表示されます。「create an empty hardhat.config.js」を選択してください:
これにより、プロジェクトのセットアップ(ステップ13で)を記述するhardhat.config.jsファイルが生成されます。
ステップ9:プロジェクトフォルダを追加する
プロジェクトを整理するために、2つの新しいフォルダを作成します。コマンドラインでプロジェクトのルートディレクトリに移動し、次のように入力してください:
**contracts/**はNFTスマートコントラクトのコードを保管する場所です
scripts/はスマートコントラクトのデプロイやそれとのやり取りに使うスクリプトを保管する場所です
ステップ10:コントラクトを書く
環境構築が完了したので、いよいよ本題であるスマートコントラクトのコードを書いていきます!
my-nftプロジェクトをお好みのエディタで開いてください(私たちはVSCodeを使っています)。スマートコントラクトはSolidityという言語で書かれており、これを使ってMyNFT.solスマートコントラクトを記述します。
-
「contracts」フォルダに移動し、MyNFT.solという新しいファイルを作成してください
-
以下が私たちのNFTスマートコントラクトのコードで、OpenZeppelinライブラリのERC721実装をベースにしています。以下の内容をコピーしてMyNFT.solファイルに貼り付けてください。
注:スマートコントラクトを通じてNFTに価格を設定したい場合は、このチュートリアルを参照してください。
- OpenZepplinのコントラクトライブラリからクラスを継承しているため、コマンドラインで次を実行してライブラリをフォルダにインストールしてください:
textnpm install @openzeppelin/contracts@3.1.0-solc-0.7
さて、このコードは実際には何をしているのでしょうか?1行ずつ見ていきましょう。
5〜7行目で、私たちのコードは3つのOpenZepplinスマートコントラクトクラスを継承しています:
-
@openzeppelin/contracts/token/ERC721/ERC721.solには、私たちのNFTスマートコントラクトが継承するERC721標準の実装が含まれています(有効なNFTであるためには、スマートコントラクトがERC721標準のすべてのメソッドを実装している必要があります)。継承されるERC721関数について詳しく知りたい場合は、こちらのインターフェース定義を確認してください。
-
@openzeppelin/contracts/utils/Counters.solは、1ずつしか増減できないカウンターを提供します。私たちのスマートコントラクトでは、このカウンターを使ってミントされたNFTの総数を管理し、新しいNFTに固有のIDを割り当てます。スマートコントラクトを使ってミントされる各NFTには固有のIDが割り当てられる必要があります――ここでは、その固有IDは単に存在するNFTの総数によって決まります。例えば、このスマートコントラクトで最初にミントするNFTのIDは「1」、2番目にミントするNFTのIDは「2」となります。
-
@openzeppelin/contracts/access/Ownable.solは、スマートコントラクトにアクセス制御を設定し、スマートコントラクトの所有者(あなた)だけがNFTをミントできるようにします。なお、アクセス制御を含めるかどうかは完全に任意です。誰でもこのスマートコントラクトを使ってNFTをミントできるようにしたい場合は、10行目のOwnableと17行目のonlyOwnerを削除してください。
10〜28行目には、私たちのカスタムNFTスマートコントラクトがあります。驚くほど短く、カウンター、コンストラクタ、そして1つの関数だけで構成されています!これは、私たちが継承しているOpenZepplinのコントラクトが、ownerOf(NFTの所有者を返す)やtransferFrom(NFTの所有権を移転する)など、NFTを作成するために必要なほとんどのメソッドを実装してくれているおかげです。
14行目で、"MyNFT"と"NFT"という2つの文字列をERC721コンストラクタに渡していることに気づくでしょう。1つ目の変数はスマートコントラクトの名前、2つ目はそのシンボルです。これらの変数名はお好きに付けて構いません!
最後に、16行目から始まるmintNFT()関数によってNFTをミントできます!この関数は2つの変数を受け取ることに注目してください:
-
address recipientは、新しくミントされたNFTを受け取るアドレスを指定します
-
string memory tokenURIは、NFTのメタデータを記述したJSONドキュメントを指す文字列です。NFTのメタデータこそがNFTに命を吹き込むものであり、名前、説明、画像、その他の属性といった追加のプロパティを持たせることができます。このチュートリアルのPart 2では、このメタデータの設定方法について説明します。
mintNFTは継承したERC721ライブラリのいくつかのメソッドを呼び出し、最終的には新しくミントされたNFTのIDを表す数値を返します。
ステップ11:MetaMaskとAlchemyをプロジェクトに接続する
Metamaskウォレット、Alchemyアカウントを作成し、スマートコントラクトも書き終えたので、いよいよこの3つを接続します。
仮想ウォレットから送信されるすべてのトランザクションには、固有の秘密鍵を使った署名が必要です。この権限をプログラムに与えるために、秘密鍵(とAlchemy APIキー)を環境ファイルに安全に保存します。
トランザクションの送信について詳しく知りたい場合は、web3を使ったトランザクション送信についてのこのチュートリアルを確認してください。
まず、プロジェクトディレクトリにdotenvパッケージをインストールします:
次に、プロジェクトのルートディレクトリに**.env**ファイルを作成し、Metamaskの秘密鍵とAlchemy APIのHTTP URLを追加します。
注:.envファイルの名前は必ず.envにしてください!xx.envのように名前を変更しないでください
-
こちらの手順に従って、Metamaskから秘密鍵をエクスポートしてください
-
Alchemy APIのHTTP URLの取得方法は以下を参照し、クリップボードにコピーしてください

.envは次のようになるはずです:
ステップ12:Ethers.jsをインストールする
Ethers.jsは、標準的なJSON-RPCメソッドをより使いやすいメソッドでラップすることで、Ethereumとのやり取りやリクエストを容易にするライブラリです。
Hardhatでは、追加のツールや機能拡張のためにプラグインを統合するのが非常に簡単です。今回はコントラクトのデプロイにEthersプラグインを活用します(Ethers.jsには非常に使いやすいコントラクトデプロイ用のメソッドが用意されています)。
プロジェクトディレクトリで次のように入力してください:
次のステップでは、hardhat.config.js内でもethersを読み込む必要があります。
ステップ13:hardhat.config.jsを更新する
ここまででいくつかの依存パッケージやプラグインを追加してきたので、今度はhardhat.config.jsを更新して、これらすべてをプロジェクトが認識できるようにする必要があります。
hardhat.config.jsを次のように更新してください:
ステップ14:コントラクトをコンパイルする
ここまでの作業が正しく進んでいるか確認するために、コントラクトをコンパイルしてみましょう。compileタスクはHardhatに組み込まれているタスクの1つです。
コマンドラインから次を実行してください:
SPDXライセンス識別子がソースファイルに指定されていない旨の警告が出るかもしれませんが、心配ありません――それ以外は問題なく動作しているはずです!もし問題があれば、Alchemyダッシュボードからサポートチケットを開くことができます。
ステップ15:デプロイスクリプトを書く
コントラクトの記述と設定ファイルの準備が整ったので、いよいよコントラクトのデプロイスクリプトを書いていきます。
**scripts/**フォルダに移動し、deploy.jsという新しいファイルを作成して、次の内容を追加してください:
Hardhatは、これらのコード行それぞれが何をしているかについて、Contractsチュートリアルの中で見事に説明しています。ここではその説明をそのまま採用しています。
ethers.jsにおけるContractFactoryは、新しいスマートコントラクトをデプロイするための抽象化であり、ここでのMyNFTは私たちのNFTコントラクトのインスタンスを生成するためのファクトリです。hardhat-ethersプラグインを使用する場合、ContractFactoryとContractのインスタンスはデフォルトで最初のsignerに接続されます。
ContractFactoryに対してdeploy()を呼び出すとデプロイが開始され、Contractに解決されるPromiseが返されます。これは、私たちのスマートコントラクトの各関数に対応するメソッドを持つオブジェクトです。
ステップ16:コントラクトをデプロイする
いよいよスマートコントラクトをデプロイする準備が整いました!プロジェクトディレクトリのルートに戻り、コマンドラインで次を実行してください:
すると、次のような出力が表示されるはずです:
Sepolia Etherscanにアクセスし、自分のコントラクトアドレスを検索すると、正常にデプロイされたことが確認できるはずです。トランザクションは次のような見た目になります:

FromアドレスはあなたのMetamaskアカウントアドレスと一致し、Toアドレスには「Contract Creation」と表示されるはずです。トランザクションをクリックすると、Toフィールドにコントラクトアドレスが表示されます:

裏側で何が起きているかを把握するために、AlchemyダッシュボードのExplorerタブに移動してみましょう。複数のAlchemyアプリを持っている場合は、必ずアプリでフィルタリングして「MyNFT」を選択してください。

ここでは、**.deploy()**関数を呼び出した際に、HardhatやEthersが裏側で行った一連のJSON-RPC呼び出しを確認できます。
ここで特に重要な2つを挙げると、**eth_sendRawTransactionは実際にスマートコントラクトをSepoliaチェーンに書き込むためのリクエストで、eth_getTransactionByHash**はトランザクションハッシュをもとにそのトランザクションに関する情報を読み取るためのリクエストです(トランザクション送信時によく見られるパターンです)。
トランザクションの送信について詳しく知りたい場合は、Web3を使ったトランザクション送信についてのこちらのチュートリアルを確認してください。
このチュートリアルのPart Iはここまでです。Part IIでは、実際にNFTをミントすることでスマートコントラクトとやり取りし、Part IIIではMetamaskでNFTを表示する方法を説明します!🤑
Alchemy Newsletter
リリース情報をいち早く受け取る
ニュースレターに登録する
Alchemyの最新のプロダクト情報とリソースをお届けします
メールアドレスを入力すると、当社のマーケティング情報およびプロダクト最新情報の受信に同意したことになります。Alchemyが受け取った情報をプライバシー通知に従って取り扱うことに同意するものとします。購読はいつでも解除できます。
関連記事

Glamsterdam: Ethereum開発者のための完全ガイド
GlamsterdamはSepoliaで稼働中です。開発者にとって何を意味するか、Alchemyがネットワークアップグレードにどう備えたかをまとめた完全ガイドです。

東京で構築するなら、どのRPCプロバイダーを選ぶべきか
東京を提供するRPCプロバイダー5社を、5つのチェーンでベンチマークした。比較結果と、レイテンシに敏感なチームにとって差が出るポイントを示す。

業界最速クラスの速度と信頼性を実現するSolana RPC読み取りの設計
AlchemyはSolanaの読み取りレイテンシが最も低く、9.21ミリ秒で、次点のプロバイダーより約26%高速です。