このハンズオンでは、OpenZeppelinを使用してERC721標準のNFTコントラクトを実装、テスト、デプロイする方法を学びます。
このハンズオンで実装するSimpleNFTコントラクトは以下の機能を持ちます:
- ✅ ERC721標準準拠:NFTの基本機能(転送、所有権管理など)
- ✅ メタデータストレージ:各NFTに固有のURIを設定
- ✅ ミント機能:新しいNFTを発行
- ✅ アクセス制御:オーナーのみがミント可能
npm install @openzeppelin/contracts- Solidity: ^0.8.28
- OpenZeppelin Contracts: ^5.4.0
- Hardhat: ^3.0.7
- Viem: ^2.38.0
contracts/SimpleNFT.solファイルに以下の主要機能が実装されています:
- ERC721: NFTの基本機能
- ERC721URIStorage: トークンURIの保存機能
- Ownable: オーナーによるアクセス制御
// NFTをミントする(オーナーのみ)
function safeMint(address to, string memory uri) public onlyOwner returns (uint256)
// 現在のトークンIDを取得
function getCurrentTokenId() public view returns (uint256)
// トークンのURIを取得
function tokenURI(uint256 tokenId) public view returns (string memory)// トークンIDのカウンター
uint256 private _nextTokenId;
// コンストラクタでNFTの名前とシンボルを設定
constructor() ERC721("SimpleNFT", "SNFT") Ownable(msg.sender) {
_nextTokenId = 0;
}以下のテストケースを実装しています:
- ✅ コントラクト名とシンボルが正しく設定されているか
- ✅ デプロイしたアドレスがオーナーになっているか
- ✅ 初期トークンIDが0であるか
- ✅ オーナーがNFTをミントできるか
- ✅ 複数のNFTをミントできるか
- ✅ オーナー以外がミントを試みると失敗するか
- ✅ NFTの所有者が転送できるか
# すべてのテストを実行
npm test
# SimpleNFTのテストのみ実行
npm run test:nft✔ 正しい名前とシンボルが設定されているべき
✔ デプロイしたアドレスがオーナーであるべき
✔ 初期トークンIDは0であるべき
✔ オーナーがNFTをミントできるべき
✔ 複数のNFTをミントできるべき
✔ オーナー以外はミントできないべき
✔ NFTの所有者が転送できるべき
7 passing
npm run deploy:nft.envファイルに環境変数を設定:
SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY
SEPOLIA_PRIVATE_KEY=YOUR_PRIVATE_KEY- デプロイを実行:
npm run deploy:nft:sepoliaSimpleNFTコントラクトをデプロイ中...
✅ SimpleNFTがデプロイされました: 0x5fbdb2315678afecb367f032d93f642f64180aa3
デプロイアカウント: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
📋 コントラクト情報:
名前: SimpleNFT
シンボル: SNFT
オーナー: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
scripts/mint-nft.tsを開いて、以下の値を設定します:
// デプロイしたコントラクトアドレス
const NFT_CONTRACT_ADDRESS = "0x5fbdb2315678afecb367f032d93f642f64180aa3";
// NFTを受け取るアドレス
const RECIPIENT_ADDRESS = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8";
// メタデータのURI
const TOKEN_URI = "ipfs://QmYourMetadataHash";npm run mint:nftNFTのメタデータは通常JSONフォーマットで、以下のような構造を持ちます:
{
"name": "My First NFT",
"description": "This is my first NFT!",
"image": "ipfs://QmImageHash",
"attributes": [
{
"trait_type": "Color",
"value": "Blue"
},
{
"trait_type": "Rarity",
"value": "Common"
}
]
}このJSONファイルをIPFSにアップロードし、そのURIをTOKEN_URIとして使用します。
-
バッチミント機能
- 一度に複数のNFTをミントできる機能を追加
-
最大供給量の設定
- NFTの総発行数に上限を設ける
-
ホワイトリスト機能
- 特定のアドレスのみミントできる機能
-
ロイヤリティ機能
- EIP-2981を実装して、二次販売時のロイヤリティを設定
-
Reveal機能
- ミント時は共通画像を表示し、後で本物の画像を公開
-
IPFS: メタデータと画像の分散ストレージ
-
NFTマーケットプレイス
-
ブロックエクスプローラー
このハンズオンでは以下のことを学びました:
- ✅ OpenZeppelinを使用したNFTコントラクトの実装
- ✅ ERC721標準の理解
- ✅ Solidityのテストの書き方
- ✅ コントラクトのデプロイ方法
- ✅ NFTのミント機能の実装
次は、実際にIPFSに画像をアップロードして、独自のNFTを発行してみましょう!🚀