lesson-2_webアプリケーションからNFTをmintしよう
☘️ Web アプリケーションから NFT を Mint する
前回のレッスンでは、Webアプリケーションを立ち上げました。
これから、Web アプリケーションからWeb3Mint.sol
コントラクトにアクセスして、NFT を発行するmintIpfsNFT
関数を呼び出していきましょう。
- 以前のレッスンで
mintIpfsNFT
関数はWeb3Mint.sol
に実装しました。
まず、NftUploader.jsx
内import { Button } from '@mui/material';
の下に、下記のコードを追加してください。
// NftUploader.jsx
import { ethers } from "ethers";
ここでは、フロントエンドとコントラクトを連携させるライブラリethers
をインポートしています。
まだethers
のライブラリをインストールしてなかったので、プロジェクトのルートで以下のコマンドを実行してください。
yarn workspace client add ethers@5.7.2
ethersをもっと詳しく知りたい方は、こちらをどうぞ。
次に、下記のコードをNftUploader.jsx
のconnectWallet
関数の下にaskContractToMintNft
関数を追加してください。
- フロントエンドに実装する
askContractToMintNft
関数が、コントラクトとWebサイトを連動させ、mintIpfsNFT
関数を呼び出します。
// NftUploader.jsx
const askContractToMintNft = async (ipfs) => {
const CONTRACT_ADDRESS =
"ここに Sepolia Test Network にデプロイしたコントラクトのアドレスを貼り付けてください";
try {
const { ethereum } = window;
if (ethereum) {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const connectedContract = new ethers.Contract(
CONTRACT_ADDRESS,
Web3Mint.abi,
signer
);
console.log("Going to pop wallet now to pay gas...");
let nftTxn = await connectedContract.mintIpfsNFT("sample", ipfs);
console.log("Mining...please wait.");
await nftTxn.wait();
console.log(
`Mined, see transaction: https://sepolia.etherscan.io/tx/${nftTxn.hash}`
);
} else {
console.log("Ethereum object doesn't exist!");
}
} catch (error) {
console.log(error);
}
};
1行ずつ、コードを見ていきましょう。
// NftUploader.jsx
const CONTRACT_ADDRESS =
"ここに Sepolia Test Network にデプロイしたコントラクトのアドレスを貼り付けてください";
ここでは、コントラクトのアドレスをCONTRACT_ADDRESS
に格納しています。
ルーディレクトリでもう一度下記を実行し、コントラクトのアドレスを取得してください。
yarn contract deploy
貼り付けるアドレスの例は、以下のようになります。
Contract deployed to: 0x88a0e9c2F3939598c402eccb7Ae1612e45448C04
上記のアドレスを'ここに ... 貼り付けてください'
の中身と入れ替えてください。
provider
やsigner
の概念がわからない方は、Project2-section3-lesson3を見て復習してみてください。
では、コントラクトインスタンスの説明から始めます。
// NftUploader.jsx
const connectedContract = new ethers.Contract(
CONTRACT_ADDRESS,
Web3Mint.abi,
signer
);ここでは、コントラクトへの接続を行っています。
新しいコントラクトインスタンス(=
connectedContract
)を作成するには、以下 3 つの変数をethers.Contract
関数に渡す必要があります。
CONTRACT_ADDRESS
: コントラクトのデプロイ先のアドレス(ローカル、テストネット、またはイーサリアムメインネット)
Web3Mint.abi
: コントラクトの ABI
signer
もしくはprovider
コントラクトインスタンスでは、コントラクトに格納されているすべての関数を呼び出すことができます。
もしこのコントラクトインスタンスに
provider
を渡すと、そのインスタンスは読み取り専用の機能しか実行できなくなります。一方、
signer
を渡すと、そのインスタンスは読み取りと書き込みの両方の機能を実行できるようになります。※ ABI についてはこのレッスンの終盤にて詳しく説明します。
次に、下記のコードを見ていきましょう。
// NftUploader.jsx
let nftTxn = await connectedContract.mintIpfsNFT("sample", ipfs);
console.log("Mining...please wait.");
ここでは、mintIpfsNFT
関数をコントラクトから呼び出し、await
を使用して、NFTの発行が承認(=マイニング)されるまで、処理をやめています。
console.log
では、NFTを発行するためのトランザクションが「承認中」であることを通知しています。
次に、下記のコードを見ていきましょう。
// NftUploader.jsx
await nftTxn.wait();
console.log(
`Mined, see transaction: https://sepolia.etherscan.io/tx/${nftTxn.hash}`
);
承認が終わったら、await nftTxn.wait()
が実行され、トランザクションの結果を取得します。コードが冗長に感じるかもしれませんが、大事な処理です。
console.log
では、取得したトランザクションの結果を、Etherscan URLとして出力しています。
askContractToMintNft
関数を呼び出すコードはこの後実装していくので、今は気にしないでください。
すべての変更をNftUploader.jsx
に反映させた後、ターミナルで下記を実行しみてください。
yarn client start
ローカルサーバーで、Webサイトが立ち上がり、下記のようなエラーがターミナルに出力されていれば、ここまでの実装は成功です。
Failed to compile.
src/App.js
Line 78:73: 'Web3Mint' is not defined no-undef
Search for the keywords to learn more about each error.
これから、ABIファイルを取得して、Web3Mint
変数を定義していきます。
📂 ABI ファイルを取得する
ABI(Application Binary Interface)はコントラクトの取り扱い説明書のようなものです。
Webアプリケーションがコントラクトと通信するために必要な情報が、ABIファイルに含まれています。
コントラクト1つ1つにユニークなABIファイルが紐づいており、その中には下記の情報が含まれています。
-
そのコントラクトに使用されている関数の名前
-
それぞれの関数にアクセスするために必要なパラメータとその型
-
関数の実行結果に対して返るデータ型の種類
ABIファイルは、コントラクトがコンパイルされた時に生成され、packages/contract/artifacts
ディレクトリに自動的に格納されます。
ターミナルでpackages/contract
ディレクトリに移動し、ls
を実行しましょう。
artifacts
ディレクトリの存在を確認してください。
ABIファイルの中身は、Web3Mint.json
というファイルに格納されいます。
下記を実行して、ABIファイルをコピーしましょう。
1. ターミナル上でpackges/contract
にいることを確認する(もしくは移動する)。
2. ターミナル上で下記を実行する。
code artifacts/contracts/Web3Mint.sol/Web3Mint.json
3. VS Code で
Web3Mint.json
ファイルが開かれるので、中身をすべてコピーしましょう。※ VS Code のファインダーを使って、直接Web3Mint.json
を開くことも可能です。
次に、下記を実行して、ABIファイルをWebアプリケーションから呼び出せるようにしましょう。
1. ターミナル上でclient
にいることを確認する(もしくは移動する)。
2. 下記を実行して、client/src/
の中にutils
ディレクトリを作成する。
mkdir src/utils
3. 下記を実行して、
utils
ディレクトリにWeb3Mint.json
ファイルを作成する。
touch src/utils/Web3Mint.json
4. 下記を実行して、
Web3Mint.json
ファイルを VS Code で開く。
code client/src/utils/Web3Mint.json
5. 先ほどコピーした
packages/contract/artifacts/contracts/Web3Mint.sol/Web3Mint.json
の中身を新しく作成したpackages/client/src/utils/Web3Mint.json
の中に貼り付けてください。
ABIファイルの準備ができたので、NftUploader.jsx
にインポートしまし ょう。
下記をNftUploader.jsx
内import ImageLogo from './image.svg';
の上に追加しましょう。
// NftUploader.jsx
import Web3Mint from "../../utils/Web3Mint.json";
ここでは、先ほど取得した、ABIファイルを含むWeb3Mint.json
ファイルをインポートしています。
🛠 Web3.storage
を使用する
これで、NFTをMintする準備はほとんど終わりましたが、まだ足りないものがありますね。 そうです!受け取った画像をIPFSにアップロードしてCIDを返してもらう機能が足りませんね。
まずは、Web3.storage
のライブラリをインストールしましょう!このライブラリを使うことで先ほど手作業で行ったIPFSに画像をアップロードする作業をプログラムで実装できるようになります。
プロジェクトのルートで下記を実行してください。
yarn workspace client add web3.storage@^4.5.4
そしてNftUploader.jsx
の中import { useEffect, useState } from 'react';
の下に一行を加えましょう。
// NftUploader.jsx
import { Web3Storage } from "web3.storage";
では、このWeb3Storage
を使った関数を実装していきましょう。
NftUploader.jsx
にimageToNFT
関数を実装しましょう。
// NftUploader.jsx
const imageToNFT = async (e) => {
const client = new Web3Storage({ token: API_KEY });
const image = e.target;
console.log(image);
const rootCid = await client.put(image.files, {
name: "experiment",
maxRetries: 3,
});
const res = await client.get(rootCid); // Web3Response
const files = await res.files(); // Web3File[]
for (const file of files) {
console.log("file.cid:", file.cid);
askContractToMintNft(file.cid);
}
};