ここを参考に補足しました。
https://docs.alchemy.com/alchemy/tutorials/how-to-create-an-nft
Metaファイル
まずは適当なイメージを、例えばGoogle Cloud Storageなどにアップロードして公開します。
その後、下記のようなJSONファイルを作って、こちらも公開しておきます
大事なのはJSONファイルを格納するフォルダで、フォルダのURLが BASE TOKEN URL
となります。ファイル名は必ず 数字(uint256) にします。拡張子はつけません。数字は0からでなくてもよいです。
{
"name": "Item Name",
"description": "Description",
"image": "https://url.png"
}
プロジェクト作成
nvm や yarn は設定済みだとします。nodeは17.xx はエラーが出るので16.xxを使います。
nvm use 16.14.0 # DO NOT USE 17.xx.xx
mkdir my-nft
cd my-nft
yarn init –y
yarn add --dev hardhat
yarn hardhat
# SELECT => Create an empty hardhat.config.js
yarn add @openzeppelin/contracts ethers @alch/alchemy-web3
yarn add --dev dotenv @nomiclabs/hardhat-ethers
mkdir contracts
mkdir scripts
ここ使っている Hardhat はローカルChainなどを起動できるBlockchain用の開発ツール群です。類似プロダクトにTruffleがあります。
OpenZeppelin はBlockchain用のライブラリ集です。
Contract
NFTをChain上に生成するにはContractが必要になります。Solidityという言語で書き、BinaryにコンパイルしChain上にdeployします。
Contractには最低限、下記の情報が必要になります。
- コントラクト名(MyNFTとか)
- シンボル (MYTとか)
- BASE TOKEN URL (メタJSONの格納フォルダ)
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;
import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol";
contract MyNFT is ERC721PresetMinterPauserAutoId {
constructor()
ERC721PresetMinterPauserAutoId(
"MyNFT",
"MYT",
"https://storage.for.meta/"
)
{}
}
Deploy Script
contracts/MyNFT.sol
とhardhat.config.js
のSolidityのバージョンの整合性を取るよう修正します。
デプロイファイルを作成します。
async function main() {
const MyNFT = await ethers.getContractFactory('MyNFT');
const myNFT = await MyNFT.deploy(); // Instance of the contract
console.log('Contract deployed to address:', myNFT.address);
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
Localhostへデプロイ
まずはLocalhostへデプロイしてみます。まずは、ローカルにBlockchainのノードを起動します。
yarn hardhat node
# Account #0: 0x012abc... (10000 ETH)
# Private Key: 0x012abc...
アカウント情報が表示されるので、1番目の公開アドレスとプライベートキーをメモしておきます。
nodeプロセスはそのままにして、別ターミナルなどで下記スクリプトを実行するとローカルへデプロイできます。
yarn hardhat run scripts/deploy.js
# Contract deployed to address: 0x0123abc...
ここで表示されるアドレスがCONTRACT ADDRESS
です。
設定ファイル
実際MintするにはこのCONTRACT ADDRESS
アドレスや自分のPRIVATE KEY
などが必要になるんですが、LocalhostとRinkebyの両方にデプロイしたいので、設定ファイルを作りたいと思います。このファイルには秘密鍵が書かれるので絶対公開しないでください。
{
"localhost": {
"public_key": "0x0123abc...",
"private_key": "0x0123abc...",
"provider_url": "http://localhost:8545",
"contract": {
"address": "0x0123abc..."
}
}
}
それぞれ次の値を設定します。
- public_key : ローカルノードのアカウントの公開鍵(アドレス)
- private_key : ローカルノードのアカウントの秘密鍵
- provider_url : ロカールは変更しなくていいです。
- contract / address : ここに先ほどデプロイした
CONTRACT ADDRESS
を設定します。
ローカルにMint
mintファイルを作成します。
const hre = require('hardhat');
const Web3 = require('web3');
const Config = require('config');
const { createAlchemyWeb3 } = require('@alch/alchemy-web3');
const Contract = require('../artifacts/contracts/MyNFT.sol/MyNFT.json');
async function main() {
const config = Config[hre.network.name];
const web3 = createAlchemyWeb3(config.provider_url);
const contract = new web3.eth.Contract(Contract.abi, config.contract.address);
const nonce = await web3.eth.getTransactionCount(config.public_key, 'latest');
const tx = {
from: config.public_key,
to: config.contract.address,
nonce: nonce,
gas: 500000,
data: contract.methods.mint(config.public_key).encodeABI(),
};
const signedTx = await web3.eth.accounts.signTransaction(
tx,
config.private_key
);
const transactionReceipt = await web3.eth.sendSignedTransaction(
signedTx.rawTransaction
);
console.log(`Transaction Hash: ${transactionReceipt.transactionHash}`);
}
main();
Mint on local network.
yarn hardhat run scripts/mint.js
RinkebyのETH取得
テストネットワークでも、デプロイするためにはガス代が必要になります。現金は必要なく、下記のようなFaucet(蛇口)と呼ばれるサイトで取得することができます。
Rinkeby APIキー取得
Alchemy にアカウントを作って API URL
を取得します。
設定ファイル
Rinkebyの設定を記入します。
{
"localhost": {
...
},
"rinkeby": {
"public_key": "0x0123abc...",
"private_key": "0x0123abc...",
"provider_url": "https://eth-rinkeby.alchemyapi.io/v2/0x0123abc...",
}
}
それぞれ次の値を設定します。
- public_key : 自分のWalletの公開鍵(アドレス)
- private_key : 自分のWalletのアカウントの秘密鍵
- provider_url : Alchemyの
API URL
Rinkebyへデプロイ
Rinkebyでデプロイします。少し時間がかかります。ETHがある程度無いとガス代不足のエラーになります。
yarn hardhat run scripts/deploy.js --network rinkeby
# Contract deployed to address: 0x0123abc
デプロイが終わると CONTRACT ADDRESS
が得られるので、そのアドレスを設定ファイルに記載します。
{
"rinkeby": {
"public_key": "0x0123abc...",
"private_key": "0x0123abc...",
"provider_url": "https://eth-rinkeby.alchemyapi.io/v2/0x0123abc...",
"contract": {
"address": "0x0123abc"
}
}
}
RinkebyへMint
Mintはデプロイと同じようにするだけです。
yarn hardhat run scripts/mint.js --network rinkeby
# Transaction Hash: 0x0123abc
トランザクションのHashが表示されるので、Rinkeby Etherscanで処理の状態を確認します。
その後、OpenSea Testnetsで画像が出ているかどうかを確認します。画像が出てない場合、メタファイルへのパスが間違ってる場合があります。メタファイル拡張子がついてると参照できません。メタファイルを変更した場合、OpenSea上でメタファイルのリフレッシュ機能を利用することができます。