NFT ERC721コントラクトの書き方とデプロイ(イーサリアム用NFT解説書 part1 )
本ページ概要:NFT ERC721コントラクトの書き方とデプロイ(イーサリアム用NFT解説書 part1 )
こちらはイーサリアム.orgのNFTチュートリアルと筆者の経験を元にこのパート1では書き方とデプロイ、パート2 NFT ERC721のMintの仕方ではスマートコントラクトを使用してNFTを作成する方法を説明します。
2021 NFTがブロックチェーンを世間に広めている今、Ethereumブロックチェーンに独自のNFT(ERC-721トークン)を公開することで、誇大広告を理解する絶好の機会です! Alchemyは、Makersplace(最近、Christie’sで6,900万ドルで記録的なデジタルアートワークの販売を記録)、Dapper Labs(NBA Top Shot&Crypto Kittiesの作成者)、OpenSea(世界最大NFTマーケットプレイス)、Zora、Super Rare、NFTfi、Foundation、Enjin、Origin Protocol、Immutableなど。
MetaMask、Solidity、Hardhat、Pinata、Alchemy、npmを使用して、RopstenテストネットワークでERC-721スマートコントラクトを作成してデプロイする手順を説明します(これが何を意味するのかをまだ理解していない場合は、心配しないでください—説明します!)。
Alchemyの初期設定
イーサリアムネットワークにつなげる。
イーサリアムブロックチェーンにリクエストを送信する方法はたくさんありますが、簡単にするために、ブロックチェーン開発者プラットフォームでありAPIであるAlchemyの無料アカウントを使用して、独自のノードを実行しなくてもイーサリアムチェーンと通信できるようにします。 このチュートリアルでは、Alchemyの開発者ツールを利用して監視と分析を行い、スマートコントラクトの展開の内部で何が起こっているのかを理解します。 Alchemyアカウントをまだお持ちでない場合は、こちらから無料で登録できます。
APPとAPIキーの作成
Alchemyアカウントを作成したら、アプリを作成してAPIキーを生成できます。 これにより、イーサリアムのテストネットワークの一つのRopstenテストネットワークにリクエストを送信できるようになります。
- ナビゲーションバーの[アプリ]にカーソルを合わせ、[アプリの作成]をクリックして、Alchemyダッシュボードの[アプリの作成]ページに移動します。
- アプリに名前を付け、簡単な説明を入力し、環境の「Staging」を選択し、ネットワークを「Ropsten」にします。
- 「Create app」をクリックすると、それだけです。 アプリは下の表に表示されます。
APIキーの取得
取得は下記のように行います。
METAMASKの設定
イーサリアムアカウント (アドレス)の作成
トランザクションを送受信するには、イーサリアムアカウントが必要です。 このチュートリアルでは、Ethereumアカウントアドレスの管理に使用されるブラウザの仮想ウォレットであるMetaMaskを使用します。 ここから無料でMetaMaskアカウントをダウンロードして作成できます。 アカウントを作成するとき、またはすでにアカウントをすでに持っている場合は「Ropsten Test Network」に切り替えます。(実際のETHを扱わらない、テスト環境での実施のため)。
テスト環境でのETHをFAUCETより獲得
スマートコントラクトをテストネットワークに採用するには、テストネットワークのETHが必要になります。 ETHを取得するには、テストするテストネットワークRopstenのFAUCETに移動して、Ropstenネットワーク上のETHのアドレスを入力し、[Send RopstenETH]をクリックします。 すぐにMetaMaskアカウントにETHが表示されるはずです!
バランス(ETH)の確認
バランス(ETH)が取れていることを再確認しましょう。METAMASKからの確認とAlchemyのコンポーザーツールを使用してeth_getBalanceリクエストを作成しても可能です。 これにより、ウォレット内のETHの量が返されます、アドレスを入力して[リクエストの送信]をクリックすると表示されます。。 MetaMaskアカウントで確認してももちろん問題ないです。
NOTE: 注:この結果は、ETHではなくweiになります。 WeiはETHの最小のデノミとして使用されます。 weiからETHへの変換は1eth = 1018weiです。 したがって、0xde0b6b3a7640000を10進数に変換すると、1 * 1018 weiが得られます。これは、1ETHに相当します。.
npmプロジェクトの設定
npmプロジェクトをイニシャライズ
ここで言うプロジェクトはnpmを使用してNFTをデプロイしようとするプロジェクトです。まずはフォルダを作成します。お気に入りのターミナルで開きます(VSCodeなど)。
mkdir my-nft cd my-nft
プロジェクトフォルダ内で、npm initを使用してプロジェクトを初期化します。 npmをまだインストールしていない場合は、次の手順に従ってください(Node.jsも必要になるため、ダウンロードしてください)。
npm init
こちらが実施画面です。
This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help init` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (my-nft) version: (1.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to C:\Users\Dell\blockchain\my-nft\package.json: { "name": "my-nft", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } Is this OK? (yes) y
package.jsonを承認して準備が整います
ハードハット(HARDHAT)のプロジェクトの設定
ハードハット(HARDHAT)のインストール
Hardhatは、Ethereumソフトウェアをコンパイル、デプロイ、テスト、およびデバッグするための開発環境です。 ライブチェーンにデプロイする前に、開発者がスマートコントラクトとdAppをローカルで構築するのに役立ちます。 my-nftプロジェクトの実行内:
npm install --save-dev hardhat
インストール手順の詳細については、このページをご覧ください。
ハードハットのプロジェクトの作成
プロジェクトフォルダ内で実行します:
npx hardhat
次に、ウェルカムメッセージと、実行する操作を選択するためのオプションが表示されます。 「空のhardhat.config.jsを作成する」を選択します。
888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 888 888 "88b 888P" d88" 888 888 "88b "88b 888 888 888 .d888888 888 888 888 888 888 .d888888 888 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 ? Welcome to Hardhat v2.0.11 ? ? What do you want to do? … Create a sample project ❯ Create an empty hardhat.config.js Quit
これにより、hardhat.config.jsファイルが生成されます。このファイルで、プロジェクトのすべてのセットアップを指定します(ステップ13)。
ERC721NFTプロジェクトの準備 、すべてを接続してコンパイル
プロジェクトフォルダの作成
プロジェクトを整理するために、2つの新しいフォルダを作成します。 コマンドラインでプロジェクトのルートディレクトリに移動し、次のように入力します。
mkdir contracts mkdir scripts
- contracts/ NFTスマートコントラクトコードを保持する場所です
- scripts/ スマートコントラクトを展開して操作するためのスクリプトを保持する場所
スマートコントラクトを書く
環境が設定されたのでスマートコントラクトコードを記述します。
スマートコントラクトは、MyNFT.sol(適当なプロジェクトの名前)スマートコントラクトを作成するために使用するSolidityと呼ばれる言語で作成します。
contracts
フォルダに移動して、MyNFT.solという新しいファイルを作成します- 以下は、OpenZeppelinライブラリのERC-721実装に基づいたNFTスマートコントラクトコードです。 以下の内容をコピーしてMyNFT.solファイルに貼り付けますimport(取り込み、継承できるように)。
//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721) // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; contract MyNFT is ERC721URIStorage, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor() public ERC721("MyNFT", "NFT") {} function mintNFT(address recipient, string memory tokenURI) public onlyOwner returns (uint256) { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _mint(recipient, newItemId); _setTokenURI(newItemId, tokenURI); return newItemId; } }
では、このコードは正確に何をするのでしょうか? 行ごとに分類してみましょう。
スマートコントラクトの最上位に、3つのOpenZeppelinスマートコントラクトクラスをインポートします。
- @ openzeppelin / Contracts / token / ERC721 / ERC721.solには、NFTスマートコントラクトが継承するERC-721標準の実装が含まれています。 (有効なNFTであるためには、スマートコントラクトはERC-721標準のすべてのメソッドを実装する必要があります。)継承されたERC-721関数の詳細については、こちらのインターフェース定義を確認してください。
- @ openzeppelin / Contracts / utils / Counters.solは、1つだけインクリメントまたはデクリメントできるカウンターを提供します。 スマートコントラクトは、カウンターを使用して、作成されたNFTの総数を追跡し、新しいNFTに一意のIDを設定します。 (スマートコントラクトを使用して作成された各NFTには一意のIDを割り当てる必要があります。ここで、一意のIDは、存在するNFTの総数によって決まります。たとえば、スマートコントラクトで最初に作成したNFTのIDは「1」です。 「2番目のNFTのIDは「2」などです。)
- @ openzeppelin / Contracts / access / Ownerable.solは、スマートコントラクトにアクセス制御を設定するため、スマートコントラクトの所有者(あなた)のみがNFTを作成できます。 (アクセス制御を含めることは完全に好みです。スマートコントラクトを使用してNFTを作成できるようにする場合は、10行目でOwnable、17行目でonlyOwnerという単語を削除してください。)
ステートメントの後に、カスタムNFTスマートコントラクトがあります。これは驚くほど短く、カウンター、コンストラクター、および単一の関数のみが含まれています。 これは、NFTの所有者を返すownerOfやNFTの所有権をあるアカウントから別のアカウントに譲渡するtransferFromなど、NFTを作成するために必要なほとんどのメソッドを実装する継承されたOpenZeppelinコントラクトのおかげです。
ERC-721コンストラクターでは、「MyNFT」と「NFT」の2つの文字列を渡すことに気付くでしょう。 最初の変数はスマートコントラクトの名前であり、2番目の変数はそのシンボルです。 これらの各変数には、好きな名前を付けることができます。
最後に、NFTを作成できる関数 mintNFT(address recipient, string memory uri)
があります。 この関数は2つの変数を取ります。
address recipient
新しく作成されるNFTを受信するアドレスを指定しますstring memory tokenURI
NFTのメタデータを説明するJSONドキュメントに解決する必要がある文字列です。 NFTのメタデータは、実際にそれを実現するものであり、名前、説明、画像、その他の属性などの構成可能なプロパティを持つことができます。 このチュートリアルのパート2では、このメタデータを構成する方法について説明します。
mintNFT
継承されたERC-721ライブラリからいくつかのメソッドを呼び出し、最終的には新しく作成されたNFTのIDを表す番号を返します。
METAMASKとALCHEMYをプロジェクトに接続します
MetaMaskウォレット、Alchemyアカウントを作成し、スマートコントラクトを作成したので、3つを接続します。 仮想ウォレットから送信されるすべてのトランザクションには、一意の秘密鍵を使用した署名が必要です。 プログラムにこの権限を与えるために、秘密鍵(およびAlchemy API鍵)を環境ファイルに安全に保存できます。 トランザクションの送信の詳細については、web3を使用したトランザクションの送信に関するこのチュートリアルをご覧ください。 まず、プロジェクトディレクトリにdotenvパッケージをインストールします。
npm install dotenv --save
次に、プロジェクトのルートディレクトリに.envファイルを作成し、MetaMask秘密鍵とHTTP Alchemy APIURLを追加します。
- これらの手順に従って、MetaMaskから秘密鍵をエクスポートします
- HTTP Alchemy API URLを取得してクリップボードにコピーするには、以下を参照してください
.envは次のようになります
API_URL="https://eth-ropsten.alchemyapi.io/v2/your-api-key" PRIVATE_KEY="your-metamask-private-key"
これらを実際にコードに接続するには、hardhat.config.jsファイルでこれらの変数を参照します。
ETHERS.JSのインストール
atを使用すると、標準のJSON-RPCメソッドをよりユーザーフレンドリーなメソッドでラップすることで、イーサリアムへのやり取りやリクエストを簡単に行うことができます。
Hardhatを使用すると、プラグインを非常に簡単に統合して、追加のツールや拡張機能を利用できます。 契約のデプロイにはEthersプラグインを利用します(Ethers.jsには非常にクリーンな契約のデプロイ方法がいくつかあります)。
プロジェクトディレクトリに次のように入力します。
npm install --save-dev @nomiclabs/hardhat-ethers 'ethers@^5.0.0'
次のステップでは、hardhat.config.jsにもエーテルが必要です。.
HARDHAT.CONFIG.JSの設定
これまでにいくつかの依存関係とプラグインを追加しましたが、プロジェクトがそれらすべてを認識できるように、hardhat.config.jsを設定する必要があります。
次のようにします。:
/** * @type import('hardhat/config').HardhatUserConfig */ require('dotenv').config(); require("@nomiclabs/hardhat-ethers"); const { API_URL, PRIVATE_KEY } = process.env; module.exports = { solidity: "0.8.0", defaultNetwork: "ropsten", networks: { hardhat: {}, ropsten: { url: API_URL, accounts: [`0x${PRIVATE_KEY}`] } }, }
コントラクトをコンパイル
これまでのところすべてが機能していることを確認するために、契約をまとめましょう。 コンパイルタスクは、組み込みのハードハットタスクの1つです。
コマンドラインから実行します。
npx hardhat compile
ソースファイルで提供されていないSPDXライセンス識別子に関する警告が表示される場合がありますが、それについて心配する必要はありません。他のすべてが正常に見えることを願っています。
※NFTチュートリアル通りだとこちらがどこか抜けているのかここでエラーなのでこちらを先にインポートしてしまいました。
npm install @openzeppelin/contracts
ERC721コントラクトのデプロイ
デプロイスクリプトの記述
コントラクトが作成され、構成ファイルが準備できたので、コントラクトデプロイスクリプトを作成します。
scripts /フォルダーに移動し、deploy.jsという名前の新しいファイルを作成して、次のコンテンツを追加します。
async function main() { const MyNFT = await ethers.getContractFactory("MyNFT") // Start deployment, returning a promise that resolves to a contract object const myNFT = await MyNFT.deploy() console.log("Contract deployed to address:", myNFT.address) } main() .then(() => process.exit(0)) .catch((error) => { console.error(error) process.exit(1) })
Hard Hatは、コントラクトチュートリアルでこれらのコード行のそれぞれが何をするかを説明する素晴らしい仕事をしています。ここでそれらの説明を採用しました。
const MyNFT = await ethers.getContractFactory("MyNFT");
ethers.jsのContractFactoryは、新しいスマートコントラクトをデプロイするために使用される抽象化であるため、ここでのMyNFTは、NFTコントラクトのインスタンスのファクトリです。 hardhat-ethersプラグインを使用する場合、ContractFactoryおよびContractインスタンスはデフォルトで最初の署名者に接続されます。
const myNFT = await MyNFT.deploy();
ContractFactoryでdeploy()をすべて実行すると、デプロイメントが開始され、Contractに解決されるPromiseが返されます。 これは、スマートコントラクト機能ごとにメソッドを持つオブジェクトです。
コントラクトのデプロイ
ついにスマートコントラクトを展開する準備が整いました! プロジェクトディレクトリのルートに戻り、コマンドラインで次のコマンドを実行します。
npx hardhat run scripts/deploy.js --network ropsten
次に、次のようなものが表示されます。
Contract deployed to address: 0xF794f2B2b463b8BFDaBdd129fA957236639E1cba
Ropsten etherscanにアクセスして契約アドレスを検索すると、正常にデプロイされていることがわかります。 トランザクションは次のようになります。
FromアドレスはMetaMaskアカウントアドレスと一致する必要があり、Toアドレスには「ContractCreation」と表示されます。 取引をクリックすると、[宛先]フィールドに契約アドレスが表示されます。
NFTスマートコントラクトをイーサリアムチェーンにデプロイしました! 内部で何が起こっているのかを理解するために、の[エクスプローラー]タブに移動してみましょう。 複数のAlchemyアプリがある場合は、必ずアプリでフィルタリングして「MyNFT」を選択してください。
.deploy()関数を呼び出したときに、Hardhat / Ethersが内部で行ったJSON-RPC呼び出しがいくつか表示されます。 ここで呼び出す2つの重要なものは、スマートコントラクトを実際にRopstenチェーンに書き込むリクエストであるeth_sendRawTransactionと、ハッシュを指定してトランザクションに関する情報を読み取るリクエストであるeth_getTransactionByHashです(トランザクションを送信するときの一般的なパターン)。 トランザクションの送信の詳細については、Web3を使用したトランザクションの送信に関するこのチュートリアルをご覧ください。