Open1

ERC720に則ったコントラクトのチュートリアル

YuheiNakasakaYuheiNakasaka

最小限のコードでIPFSにアップロードされたファイルをERC721に則ってNFTとして鋳造しRopstenへのデプロイ、Walletでの確認を行うTutorial。これを元に拡張して行くことができそう。

ERC720に則ったコントラクトのチュートリアル

リソース

やること

  • ERC720に則ったスマートコントラクトのropstenへのデプロイ

メモ

Tutorial1 - testnetへコントラクトのデプロイまで

  • Alchemyの登録とAppの作成
  • metamaskのWallet作成
  • testnetへのデプロイ用にfaucetからテストETHを取得
  • プロジェクト作成
mkdir my-nft
cd my-nft
npm init
hardhatで開発環境構築(Create an empty hardhat.config.jsを選択)
npm install --save-dev hardhat
npx hardhat
mkdir contracts
mkdir scripts
Contractを書く
npm install @openzeppelin/contracts
code contracts/MyNFT.sol
//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;
    }
}
WalletのPRIVATE_KEYとAlchemyのAPI_KEYを秘匿情報として.envに追加
npm install dotenv --save
code .env
API_URL = "https://eth-ropsten.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY = "your-metamask-private-key"
hardhatでtestnetにデプロイする準備1
npm install --save-dev @nomiclabs/hardhat-ethers 'ethers@^5.0.0'\n
code 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}`]
      }
   },
}
hardhatでtestnetにデプロイする準備2
code scripts/deploy.js
async function main() {
  const MyNFT = await ethers.getContractFactory("MyNFT")
  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)
  })
  • デプロイ
npx hardhat compile
npx hardhat run scripts/deploy.js --network ropsten

Tutorial2 - 電子データをIPFSにアップロードしてそのファイルをNFTとしてコントラクトにmintする

  • Pinataにアカウント作成
  • NFT化したいファイルをアップロードする
  • web3のインストール
npm install @alch/alchemy-web3
自分のアカウントアドレスを.envに追記
code .env
API_URL = "https://eth-ropsten.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY = "your-metamask-private-key"
PUBLIC_KEY = "your-metamask-public-address"
nftの作成をするコードの準備
code scripts/mint-nft.js
require("dotenv").config();
const API_URL = process.env.API_URL;
const PUBLIC_KEY = process.env.PUBLIC_KEY;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
 
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(API_URL);
 
// 先ほどデプロイ済みのコントラクトのAddress
const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
const contractAddress = "<your contract address>";
const nftContract = new web3.eth.Contract(contract.abi, contractAddress);
 
async function mintNFT(tokenURI) {
  const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest");
  const tx = {
    from: PUBLIC_KEY,
    to: contractAddress,
    nonce: nonce,
    gas: 500000,
    data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
  };
 
  const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY);
  signPromise
    .then((signedTx) => {
      web3.eth.sendSignedTransaction(
        signedTx.rawTransaction,
        function (err, hash) {
          if (!err) {
            console.log(
              "The hash of your transaction is: ",
              hash,
              "\nCheck Alchemy's Mempool to view the status of your transaction!"
            );
          } else {
            console.log(
              "Something went wrong when submitting your transaction:",
              err
            );
          }
        }
      );
    })
    .catch((err) => {
      console.log(" Promise failed:", err);
    });
}
 
mintNFT(
  "https://gateway.pinata.cloud/ipfs/<ipfs-hash>"
);
mintする
node scripts/mint-nft.js
成功したか確認

Tutorial3 - mintしたNFTをwalletで閲覧する

  • MetaMaskのmobile版をDLする
  • コントラクトをデプロイしたアカウントでログインする
  • Ropsten Networkに切り替える
  • NFTタブのNFTを追加へ先ほどデプロイしたスマートコントラクトのAddressとNFTのTokenIDを入力する