NFTのミント方法(NFTチュートリアルシリーズの2/3)
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_URL3const { 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にもう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にアップロードしてください。
ステップ5: コントラクトのインスタンスを作成する
ここで、私たちのコントラクトと対話するには、コード内でインスタンスを作成する必要があります インスタンスの作成には、コントラクトアドレスが必要になります。コントラクトをデプロイする際に使用したアドレスを検索することで、デプロイメントまたはEtherscan(opens in a new tab)から取得できます。
上記の例では、コントラクトのアドレスは、0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778です。
次に、Web3のコントラクトメソッド(opens in a new tab)を活用して、ABIとアドレスを使用したコントラクトを作成します。 mint-nft.js
ファイルに以下を追加します。
1const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"23const 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)
という名前の関数を定義し、次のようにトランザクションを作成してみましょう。
PRIVATE_KEYとPUBLIC_KEYを
.env
ファイルから取得します。次に、アカウントのノンスを確認します。 ノンスの指定は、あなたのアドレスから送信されたトランザクションの数を追跡するために使用されます。これは、セキュリティ目的で、リプレイ攻撃(opens in a new tab)を防ぐために必要となります。 あなたのアドレスから送信されたトランザクションの数を取得するには、 getTransactionCount(opens in a new tab)を使用します。
最後に、以下の情報を使用してトランザクションを設定します。
'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;56 const { createAlchemyWeb3 } = require("@alch/alchemy-web3");7 const web3 = createAlchemyWeb3(API_URL);89 const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");10 const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778";11 const nftContract = new web3.eth.Contract(contract.abi, contractAddress);1213 async function mintNFT(tokenURI) {14 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //get latest nonce1516 //the transaction17 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_URL3const PUBLIC_KEY = process.env.PUBLIC_KEY4const PRIVATE_KEY = process.env.PRIVATE_KEY56const { createAlchemyWeb3 } = require("@alch/alchemy-web3")7const web3 = createAlchemyWeb3(API_URL)89const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")10const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"11const nftContract = new web3.eth.Contract(contract.abi, contractAddress)1213async function mintNFT(tokenURI) {14 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce1516 //the transaction17 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 }2425 const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)26 signPromise27 .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 err41 )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
に渡します。
ハッシュコードを取得する方法をこちらにご紹介します。
別のウィンドウで
https://gateway.pinata.cloud/ipfs/<metadata-hash-code>
を読み込んでみて、コピーしたハッシュコードがmetadata.jsonにリンクしているか確認します。 以下のスクリーンショットと類似したページが表示されるはずです。
最終的には、次のようなコードになっているはずです。
1require("dotenv").config()2const API_URL = process.env.API_URL3const PUBLIC_KEY = process.env.PUBLIC_KEY4const PRIVATE_KEY = process.env.PRIVATE_KEY56const { createAlchemyWeb3 } = require("@alch/alchemy-web3")7const web3 = createAlchemyWeb3(API_URL)89const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")10const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"11const nftContract = new web3.eth.Contract(contract.abi, contractAddress)1213async function mintNFT(tokenURI) {14 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce1516 //the transaction17 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 }2425 const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)26 signPromise27 .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 err41 )42 }43 }44 )45 })46 .catch((err) => {47 console.log("Promise failed:", err)48 })49}5051mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP")すべて表示コピー
次に、node scripts/mint-nft.js
を実行してNFTをデプロイします。 数秒後にターミナル上に次のようなレスポンスが表示されるはずです。
1The hash of your transaction is: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e823Alchemyのメンプールをチェックし、あなたのトランザクションのステータスを確認しましょう。
Alchemy mempool(opens in a new tab)にアクセスして、トランザクションのステータス(保留中、マイニング中、ネットワークによってドロップされたかどうか)を確認します。 トランザクションが削除された場合は、 Sepolia Etherscan(opens in a new tab)を確認してトランザクションハッシュを検索することもできます。
EtherscanでNFTトランザクションハッシュを表示します
以上で完了です。 イーサリアムブロックチェーン上にデプロイしてNFTをミントしました。
mint-nft.js
を使えば、あなたの心(ウォレット)が望むだけ、NFTをミントすることができます。 NFTのメタデータを記述した新しいtokenURIを必ず渡してください(この作業を怠ると、異なるIDを備えた同一のものを大量に作成してしまいます)。
ウォレットにNFTを表示する方法については、パート3: ウォレットにNFTを表示する方法をご覧ください。
最終編集者: @pettinarip(opens in a new tab), 2023年11月23日