メインコンテンツへスキップ

NFTのミント方法(NFTチュートリアルシリーズの2/3)

ERC-721alchemySolidityスマートコントラクト
初級
Sumi Mudgil
2021年4月22日
13 分の読書 minute read

Beeple(opens in a new tab): $69,000,000 3LAU(opens in a new tab): $11,000,000 Grimes(opens in a new tab): $6,000,000

いずれもAlchemyの強力なAPIを使ってNFTをミントしています。 このチュートリアルでは、<10分以内でNFTをミントする方法を説明します。

「NFTのミント」とは、ブロックチェーン上にERC-721トークンのユニークなインスタンスを公開することです。 NFTチュートリアルシリーズのパート1で作成したスマートコントラクトを使って、Web3のスキルを駆使し、NFTをミントしてみましょう。 このチュートリアルが終わるころには、あなた(とウォレット) の望むがままにNFTをミントできるようになります。

さあ、始めましょう。

ステップ1: Web3をインストールする

NFTスマートコントラクトの作成に関する最初のチュートリアルに沿って進めている場合、すでにEthers.jsを使用していることと思います。 Web3はEthersと同様、イーサリアムブロックチェーンへのリクエストを簡単に作成するために使用されるライブラリです。 このチュートリアルでは、自動再試行と堅牢なWebSocketサポートを提供する拡張Web3ライブラリ、Alchemy Web3(opens in a new tab)を使用します。

プロジェクトのホームディレクトリで以下を実行します。

1npm install @alch/alchemy-web3

ステップ2: mint-nft.jsファイルを作成する

scriptsディレクトリ内にmint-nft.jsファイルを作成し、以下のコード行を追加します。

1require("dotenv").config()
2const API_URL = process.env.API_URL
3const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
4const web3 = createAlchemyWeb3(API_URL)
コピー

ステップ3: コントラクトABIを取得する

コントラクトABI(アプリケーションバイナリインターフェイス)は、スマートコントラクトと対話するためのインターフェイスです。 コントラクトABIの詳細については、こちら(opens in a new tab)をご覧ください。 Hardhatは自動的にABIを生成して、MyNFT.jsonファイルに保存します。 このABIを使用するには、mint-nft.jsに次のコードを追加して、ABIをパースする必要があります。

1const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
コピー

ABIを表示したい場合は、次のコードを追加することでコンソールに出力できます:

1console.log(JSON.stringify(contract.abi))
コピー

mint-nft.jsを実行し、コンソールに出力されたABIを表示するには、ターミナルに移動して次のコードを実行します。

1node scripts/mint-nft.js
コピー

ステップ4: IPFSを使用してNFTのメタデータを設定する

パート1のチュートリアルを思い出してください。スマートコントラクトのmintNFT関数は、NFTのメタデータを記述したJSONドキュメントで解決すべきtokenURIパラメータを取り込みます。その結果、NFTが生成され、名前、記述、画像、その他の属性などの設定可能なプロパティを実装することができます。

Interplanetary File System(IPFS)は、分散型ファイルシステムでデータを格納、共有するための分散プロトコルであり、ピアツーピアネットワークです。

私たちは、NFTアセットとメタデータを保存してNFTを真に分散化するために、便利なIPFS APIとツールキットであるPinataを使用します。 Pinataアカウントをお持ちでない場合は、こちら(opens in a new tab)から無料アカウントにサインアップし、メールアドレスの認証手順を完了してください。

アカウント作成後の手順:

  • 「Files」ページに移動し、ページの左上にある青色の「Upload」ボタンをクリックします。

  • Pinataに画像をアップロードします。これがNFTの画像アセットになります。 アセットに好きな名前を付けてください。

  • アップロード後、「Files」ページのテーブルにファイル情報が表示されます。 また、CID列も表示されます。 隣のコピーボタンをクリックするとCIDをコピーできます。 アップロードはhttps://gateway.pinata.cloud/ipfs/<CID>で確認できます。 例えば、IPFSで使われている画像は、こちら(opens in a new tab)です。

視覚型学習者のために、上記の手順を要約します。

Pinataに画像をアップロードする方法

次に、Pinataにもう1件ドキュメントをアップロードしますが、 その前にドキュメントを作成する必要があります。

ルートディレクトリにnft-metadata.jsonというファイルを新規作成し、以下のjsonコードを追加してください。

1{
2 "attributes": [
3 {
4 "trait_type": "Breed",
5 "value": "Maltipoo"
6 },
7 {
8 "trait_type": "Eye color",
9 "value": "Mocha"
10 }
11 ],
12 "description": "The world's most adorable and sensitive pup.",
13 "image": "ipfs://QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb",
14 "name": "Ramses"
15}
すべて表示
コピー

json内のデータは自由に変更できます。 属性セクションを削除または追加できます。 最も重要なことは、画像フィールドがIPFS画像の位置を指していることを確認することです。そうしないと、NFTに(とても可愛い)犬の写真が含まれます。

JSONファイルの編集が終わったら、保存して、画像のアップロードと同じ手順でPinataにアップロードしてください。

nft-metadata.jsonを Pinataにアップロードする方法

ステップ5: コントラクトのインスタンスを作成する

ここで、私たちのコントラクトと対話するには、コード内でインスタンスを作成する必要があります インスタンスの作成には、コントラクトアドレスが必要になります。コントラクトをデプロイする際に使用したアドレスを検索することで、デプロイメントまたはEtherscan(opens in a new tab)から取得できます。

Etherscanでコントラクトアドレスを表示する

上記の例では、コントラクトのアドレスは、0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778です。

次に、Web3のコントラクトメソッド(opens in a new tab)を活用して、ABIとアドレスを使用したコントラクトを作成します。 mint-nft.jsファイルに以下を追加します。

1const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
2
3const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
コピー

ステップ6: .envファイルをアップデートする

それでは、イーサリアムチェーンにトランザクションを作成して送信するために、公開されているイーサリアムのアカウントアドレスを使用してアカウントのノンスを取得します(以下で説明します)。

.envファイルにあなたの公開鍵を追加します。チュートリアルのパート1を完了している場合、.envファイルは次のようになっているはずです。

1API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key"
2PRIVATE_KEY = "your-private-account-address"
3PUBLIC_KEY = "your-public-account-address"
コピー

ステップ7: トランザクションを作成する

まず、mintNFT(tokenData)という名前の関数を定義し、次のようにトランザクションを作成してみましょう。

  1. PRIVATE_KEYPUBLIC_KEY.envファイルから取得します。

  2. 次に、アカウントのノンスを確認します。 ノンスの指定は、あなたのアドレスから送信されたトランザクションの数を追跡するために使用されます。これは、セキュリティ目的で、リプレイ攻撃(opens in a new tab)を防ぐために必要となります。 あなたのアドレスから送信されたトランザクションの数を取得するには、 getTransactionCount(opens in a new tab)を使用します。

  3. 最後に、以下の情報を使用してトランザクションを設定します。

  • 'from': PUBLIC_KEY — トランザクションの発信元は公開アドレス

  • 'to': contractAddress — 対話し、トランザクションを送信したいコントラクト

  • 'nonce': nonce — アドレスから送信されたトランザクションの数を持つアカウントのノンス

  • 'gas': estimatedGas —トランザクションを完了するために必要な推定ガス

  • 'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI() — このトランザクションで実行したい計算。今回の場合は、NFTを発行すること。

mint-nft.jsファイルは、現在このような状態になっているはずです。

1 require('dotenv').config();
2 const API_URL = process.env.API_URL;
3 const PUBLIC_KEY = process.env.PUBLIC_KEY;
4 const PRIVATE_KEY = process.env.PRIVATE_KEY;
5
6 const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
7 const web3 = createAlchemyWeb3(API_URL);
8
9 const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
10 const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778";
11 const nftContract = new web3.eth.Contract(contract.abi, contractAddress);
12
13 async function mintNFT(tokenURI) {
14 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //get latest nonce
15
16 // トランザクション
17 const tx = {
18 'from': PUBLIC_KEY,
19 'to': contractAddress,
20 'nonce': nonce,
21 'gas': 500000,
22 'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()
23 };
24 }
すべて表示
コピー

ステップ8: トランザクションに署名する

さて、トランザクションを作成したら、それを送信するために署名する必要があります。 ここで秘密鍵を使用します。

web3.eth.sendSignedTransactionはトランザクションハッシュを提供することで、トランザクションがきちんとマイニングされ、ネットワークによってドロップされていないことを確認できます。 トランザクション署名のセクションにいくつかエラーチェックを追加することで、トランザクションが正常に完了したかどうかを確認できるようにしておきます。

1require("dotenv").config()
2const API_URL = process.env.API_URL
3const PUBLIC_KEY = process.env.PUBLIC_KEY
4const PRIVATE_KEY = process.env.PRIVATE_KEY
5
6const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
7const web3 = createAlchemyWeb3(API_URL)
8
9const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
10const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
11const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
12
13async function mintNFT(tokenURI) {
14 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce
15
16 // トランザクション
17 const tx = {
18 from: PUBLIC_KEY,
19 to: contractAddress,
20 nonce: nonce,
21 gas: 500000,
22 data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
23 }
24
25 const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
26 signPromise
27 .then((signedTx) => {
28 web3.eth.sendSignedTransaction(
29 signedTx.rawTransaction,
30 function (err, hash) {
31 if (!err) {
32 console.log(
33 "The hash of your transaction is: ",
34 hash,
35 "\nCheck Alchemy's Mempool to view the status of your transaction!"
36 )
37 } else {
38 console.log(
39 "Something went wrong when submitting your transaction:",
40 err
41 )
42 }
43 }
44 )
45 })
46 .catch((err) => {
47 console.log(" Promise failed:", err)
48 })
49}
すべて表示
コピー

ステップ9: mintNFTを呼び出し、ノードmint-nft.jsを実行する

Pinataにアップロードしたmetadata.jsonを覚えているでしょうか。 Pinataからそのハッシュコードを取得し、https://gateway.pinata.cloud/ipfs/<metadata-hash-code>をパラメータとして、関数mintNFTに渡します。

ハッシュコードを取得する方法をこちらにご紹介します。

Pinataでnftメタデータハッシュコードを取得する方法Pinataでnftメタデータハッシュコードを取得する方法

別のウィンドウでhttps://gateway.pinata.cloud/ipfs/<metadata-hash-code>を読み込んでみて、コピーしたハッシュコードがmetadata.jsonにリンクしているか確認します。 以下のスクリーンショットと類似したページが表示されるはずです。

ページにjsonメタデータが表示されるはずですページにjsonメタデータが表示されるはずです

最終的には、次のようなコードになっているはずです。

1require("dotenv").config()
2const API_URL = process.env.API_URL
3const PUBLIC_KEY = process.env.PUBLIC_KEY
4const PRIVATE_KEY = process.env.PRIVATE_KEY
5
6const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
7const web3 = createAlchemyWeb3(API_URL)
8
9const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
10const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
11const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
12
13async function mintNFT(tokenURI) {
14 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce
15
16 //the transaction
17 const tx = {
18 from: PUBLIC_KEY,
19 to: contractAddress,
20 nonce: nonce,
21 gas: 500000,
22 data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
23 }
24
25 const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
26 signPromise
27 .then((signedTx) => {
28 web3.eth.sendSignedTransaction(
29 signedTx.rawTransaction,
30 function (err, hash) {
31 if (!err) {
32 console.log(
33 "The hash of your transaction is: ",
34 hash,
35 "\nCheck Alchemy's Mempool to view the status of your transaction!"
36 )
37 } else {
38 console.log(
39 "Something went wrong when submitting your transaction:",
40 err
41 )
42 }
43 }
44 )
45 })
46 .catch((err) => {
47 console.log("Promise failed:", err)
48 })
49}
50
51mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP")
すべて表示
コピー

次に、node scripts/mint-nft.jsを実行してNFTをデプロイします。 数秒後にターミナル上に次のようなレスポンスが表示されるはずです。

1The hash of your transaction is: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8
2
3Alchemyのメンプールをチェックし、あなたのトランザクションのステータスを確認しましょう。

Alchemy mempool(opens in a new tab)にアクセスして、トランザクションのステータス(保留中、マイニング中、ネットワークによってドロップされたかどうか)を確認します。 トランザクションが削除された場合は、 Sepolia Etherscan(opens in a new tab)を確認してトランザクションハッシュを検索することもできます。

EtherscanでNFTトランザクションハッシュを表示するEtherscanでNFTトランザクションハッシュを表示します

以上で完了です。 イーサリアムブロックチェーン上にデプロイしてNFTをミントしました。

mint-nft.jsを使えば、あなたの心(ウォレット)が望むだけ、NFTをミントすることができます。 NFTのメタデータを記述した新しいtokenURIを必ず渡してください(この作業を怠ると、異なるIDを備えた同一のものを大量に作成してしまいます)。

ウォレットにNFTを表示する方法については、パート3: ウォレットにNFTを表示する方法をご覧ください。

最終編集者: @mfujimori1018(opens in a new tab), 2024年4月1日

このチュートリアルは役に立ちましたか?