lesson-3_WEBアプリからコントラクトを呼び出そう
☘️ Web アプリケーションから NFT を Mint する
前回のレッスンでは、Webアプリケーションを立ち上げました。
これから、Web アプリケーションからMyEpicNFT.sol
コントラクトにアクセスして、NFT を発行するmakeAnEpicNFT
関数を呼び出していきましょう。
- 以前のレッスンで
makeAnEpicNFT
関数はMyEpicNFT.sol
に実装しました。
まず、App.js
の1行目に、下記のコードを追加してください。
// App.js
import { ethers } from "ethers";
ここでは、フロントエンドとコントラクトを連携させるライブラリethers
をインポートしています。
次に、下記のコードをApp.js
のconnectWallet
関数の下にaskContractToMintNft
関数を追加してください。
- フロントエンドに実装する
askContractToMintNft
関数が、コントラクトとWebサイトを連動させ、makeAnEpicNFT
関数を呼び出します。
// App.js
const askContractToMintNft = async () => {
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,
myEpicNft.abi,
signer
);
console.log("Going to pop wallet now to pay gas...");
let nftTxn = await connectedContract.makeAnEpicNFT();
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行ずつ、コードを見ていきましょう。
// App.js
const CONTRACT_ADDRESS =
"ここに Sepolia Test Network にデプロイしたコントラクトのアドレスを貼り付けてください";
ここでは、コントラクトのアドレスをCONTRACT_ADDRESS
に格納しています。
ETH-NFT-Collection
ディレクトリ直下で、もう一度下記を実行し、コントラクトのアドレスを取得してください。
yarn contract deploy:sepolia
貼り付けるアドレスの例は、以下のようになります。
Contract deployed to: 0x88a0e9c2F3939598c402eccb7Ae1612e45448C04
上記のアドレスを"ここに ... 貼り付けてください"
の中身と入れ替えてください。
次に、追加されたコードを見ながら、新しい概念について学びましょう。
I. provider
// App.js
const provider = new ethers.providers.Web3Provider(ethereum);
provider
を介して、ユーザーはブロックチェーン上に存在するイーサリアムノードに接続することができます。 MetaMask が提供するイーサリアムノードを使用して、デプロイされたコントラクトからデータを送受信するために上記の実装を行いました。
ethers
のライブラリによりprovider
のインスタンスを新規作成しています。
II. signer
// App.js
const signer = provider.getSigner();
signer
は、ユーザーのウォレットアドレスを抽象化したものです。
provider
を作成し、provider.getSigner()
を呼び出すだけで、ユーザーはウォレットアドレスを使用してトランザクションに署名し、そのデータをイーサリアムネットワークに送信することができます。
provider.getSigner()
は新しいsigner
インスタンスを返すので、それを使って署名付きトランザクションを送信することができます。
III. コントラクトインスタンス
// App.js
const connectedContract = new ethers.Contract(
CONTRACT_ADDRESS,
myEpicNft.abi,
signer
);ここでは、コントラクトへの接続を行っています。
新しいコントラクトインスタンス(=
connectedContract
)を作成するには、以下 3 つの変数をethers.Contract
関数に渡す必要があります。
CONTRACT_ADDRESS
: コントラクトのデプロイ先のアドレス(ローカル、テストネット、またはイーサリアムメインネット)
myEpicNft.abi
: コントラクトの ABI
signer
もしくはprovider
コントラクトインスタンスでは、コントラクトに格納されているすべての関数を呼び出すことができます。
もしこのコントラクトインスタンスに
provider
を渡すと、そのインスタンスは読み取り専用の機能しか実行できなくなります。一方、
signer
を渡すと、そのインスタンスは読 み取りと書き込みの両方の機能を実行できるようになります。※ ABI についてはこのレッスンの終盤にて詳しく説明します。
次に、下記のコードを見ていきましょう。
// App.js
console.log("Going to pop wallet now to pay gas...");
ここでは、ethers.Contract
でコントラクトと の接続を行った後、承認が開始されることを通知しています。
次に、下記のコードを見ていきましょう。
// App.js
let nftTxn = await connectedContract.makeAnEpicNFT();
console.log("Mining...please wait.");
ここでは、makeAnEpicNFT
関数をコントラクトから呼び出し、await
を使用して、NFTの発行が承認(=マイニング)されるまで、処理をやめています。
console.log
では、NFTを発行するためのトランザクションが「承認中」であることを通知しています。
次に、下記のコードを見ていきましょう。
// App.js
await nftTxn.wait();
console.log(
`Mined, see transaction: https://sepolia.etherscan.io/tx/${nftTxn.hash}`
);
承認が終わったら、await nftTxn.wait()
が実行され、トランザクションの結果を取得します。コードが冗長に感じるかもしれませんが、大事な処理です。
console.log
では、取得したトランザクションの結果を、Etherscan URLとして出力しています。
ユーザーがMint NFT
ボタンをクリックしたときに、askContractToMintNft
関数を呼び出すコードを見ていきましょう。
// App.js
return (
{currentAccount === ""
? renderNotConnectedContainer()
: (
/* ユーザーが Mint NFT ボタンを押した時に、askContractToMintNft 関数を呼び出します */
<button onClick={askContractToMintNft} className="cta-button connect-wallet-button">
Mint NFT
</button>
)
}
);
条件付きレンダリングについて復習していきましょう。
currentAccount === ""
は、currentAccount
にユーザーのウォレットアドレスが紐づいているかどうか判定しています。
条件付きレンダリングは、下記のように実行されます。
{ currentAccount === "" ? ( currentAccount にアドレスが紐づいてなければ、A を実行 ) : ( currentAccount にアドレスが紐づいれば B を実行 )}
App.js
の場合、A
並ばは、renderNotConnectedContainer()