๐Ÿง‘๐Ÿปโ€๐Ÿ’ป truffle ์ด์šฉํ•œ ERC-721๊ฐœ๋ฐœ๊ธฐ

ZEKEยท2022๋…„ 2์›” 8์ผ
0
post-thumbnail

>>> Github์ฃผ์†Œ Github_truffleERC721

๐Ÿ“Œ ๊ฐœ๋ฐœ๋ชฉํ‘œ

์˜ค๋Š˜์€ ์š”์ฆ˜ ๋Œ€์„ธ ์ค‘์— ๋Œ€์„ธ! ํ•ซ ํ•œ NFT๋ฅผ ๊ฐœ๋ฐœํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.
truffle์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ ํ™˜๊ฒฝ์„ ๊ตฌ์ถ• ํ•œ ํ›„ ์˜คํ”ˆ์ œํ”Œ๋ฆฐ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ด์šฉํ•˜์—ฌ erc721๊ธฐ๋ณธ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๊ทธ๋ฆผ์„ ํ•˜๋‚˜ ๊ณจ๋ผ Ganache์—์„œ ํ…ŒํŠธ์ŠคํŠธ ํ›„ ์ด๋”๋ฆฌ์›€ Ropsten ํ…Œ์ŠคํŠธ๋„ท์— ๋ฐฐํฌํ•˜์—ฌ ์ด๋”์Šค์บ”์—์„œ ํ•ด๋‹น ๋‚ด์—ญ์„ ํ™•์ธํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๋จผ์ € ๊ธฐ๋ณธ ๊ฐœ๋ฐœํ™˜๊ฒฝ์€ truffle์„ ์ด์šฉํ•˜๊ณ  ์ด๋ฏธ์ง€๋ฅผ ๋ฌด๋ฃŒ ์ €์žฅ์†Œ์ธ NFTStorage์— ์—…๋กœ๋“œํ•˜์—ฌ ์ด๋กœ ์–ป์–ด์ง„ tokenURI๋ฅผ ํ†ตํ•ด ์œ ์ผ๋ฌด์ดํ•œ ํ† ํฐ ERC721๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ณ ์žํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ganache์— NFT๋ฐฐํฌ

1. truffle ์ด์šฉํ•œ ๊ฐœ๋ฐœํ™˜๊ฒฝ ๊ตฌ์ถ•ํ•˜๊ธฐ

  • ๋จผ์ €, ํ”„๋กœ์ ํŠธ ํดํ„ฐ๋ฅผ ์ƒ์„ฑํ•œ ํ›„ truffle๊ณผ npm ์ดˆ๊ธฐํ™”๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
# ํด๋”์ƒ์„ฑ
mkdir truffleERC721

# ํด๋”์ง„์ž…
cd truffleERC721

# truffle ์ดˆ๊ธฐํ™”
truffle init

# npm ์ดˆ๊ธฐํ™”
npm init
  • ์ด ํ›„ ํ”„๋กœ์ ํŠธ ํด๋”์—์„œ truffle-config.js ํŒŒ์ผ์„ ์—ด์–ด ์†”๋ฆฌ๋””ํ‹ฐ ์ปดํŒŒ์ผ ๋ฒ„์ „์„ ๊ฐœ์ธ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฒ„์ „๊ณผ ๋งž์ถฐ์ฃผ๊ณ , ๋„คํŠธ์›Œํฌ๋ฅผ ์„ค์ •ํ•ด ์ฃผ๋Š”๋ฐ, ๋จผ์ € ๊ฐ€๋‚˜์Šˆ๋ฅผ ์ด์šฉํ•ด ํ…Œ์ŠคํŠธ ํ•  ๊ฒƒ ์ด๋ฏ€๋กœ ๊ฐ€๋‚˜์Šˆ์˜ port ๋ฒˆํ˜ธ 7545๋ฅผ ์ž…๋ ฅํ•ด ์ค๋‹ˆ๋‹ค.

2. openzeppelin์„ ์ด์šฉํ•˜์—ฌ NFT๋ฐœํ–‰ํ•  ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ์ž‘์„ฑํ•˜๊ธฐ

  • openzeppelin ์„ค์น˜
    openzeppelin์€ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ํšŒ์‚ฌ๋กœ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†์‰ฝ๊ฒŒ ์—ฌ๋Ÿฌ ํ† ํฐ๋“ค์„ ๋ฐœํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
# openzeppelin ์„ค์น˜
npm install @openzeppelin/contracts

  • contractsํด๋” ์•ˆ์— ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ์ž‘์„ฑ
// 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.7;

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 MyNFTs is ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() public ERC721("zekeNFTs", "ZNFT") {}

    function mintNFT(string memory tokenURI)
        public onlyOwner
        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(msg.sender, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}
  • ๋ฐฐํฌ๋ฅผ ์œ„ํ•ด migrations/1_initial_migration.js์— ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์ปจํŠธ๋ž™ํŠธ ์ถ”๊ฐ€
const Migrations = artifacts.require("Migrations");
const MyNFTs = artifacts.require("MyNFTs.sol");
module.exports = function (deployer) {
  deployer.deploy(Migrations);
  deployer.deploy(MyNFTs);
};

3. NFTStorage์ด์šฉํ•˜์—ฌ NFT๋กœ ๋ฐœํ–‰ํ•  ์ด๋ฏธ์ง€ ์—…๋กœ๋“œํ•˜๊ณ  tokenURI๊ฐ€์ ธ์˜ค๊ธฐ

  • nft.storage์— ๊ฐ€์ž…ํ•˜๊ณ  APIKeys์—์„œ ํ‚ค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  • NFT๋กœ ๋ฐœํ–‰ํ•  ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ nft.storage์— ์˜ฌ๋ ค์ฃผ๊ธฐ

npm install nft.storage

ํ”„๋กœ์ ํŠธ ํด๋” ์•ˆ์— nft.jsํŒŒ์ผ ์ƒ์„ฑํ•˜๊ณ  ์ฝ”๋“œ ์‚ฝ์ž…

import { NFTStorage, File } from "nft.storage";
import fs from "fs";

const apiKey = "Your API KEY";
const client = new NFTStorage({ token: apiKey });

const metadata = await client.store({
  name: "woodang",
  description: "carrot is cute",
  image: new File([fs.readFileSync("./woodang.png")], "woodang.png", {
    type: "image/png ",
  }),
  attributes: [
    { trait_type: "skin", value: "flash" },
    {
      trait_type: "face",
      value: "frightened",
    },
  ],
});
console.log(metadata.url);
// ipfs://bafyreib4pff766vhpbxbhjbqqnsh5emeznvujayjj4z2iu533cprgbz23m/metadata.json

์ƒ์„ฑ๋œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ!!


์ƒ์„ฑ๋œ ๋‹น๊ทผ!

4. ์ปดํŒŒ์ผํ›„ ๋ฐฐํฌํ•˜๊ธฐ

# ์ปดํŒŒ์ผ
truffle compile
# ๋ฐฐํฌ
truffle deployed
# ์ฝ˜์†” ์ ‘์†ํ•˜์—ฌ ์ƒ์„ฑํ•œ token metadata URI๋กœ NFT๋ฐœํ–‰
truffle console
truffle(ganache)> instance = await MyNFTs.deployed
truffle(ganache)> instance.name() // 'zekeNFTs'
truffle(ganache)> instance.symbol() // 'ZNFT'

๋ฐฐํฌ์™„๋ฃŒ!


๐Ÿ“Œ Ropsten์— NFT๋ฐฐํฌ

1. ganache๋ฐฐํฌ์‹œ ์‚ฌ์šฉํ•œ ํ”„๋กœ์ ํŠธ์—์„œ truffle-config.js์ˆ˜์ •

  • ๋‹ˆ๋ชจ๋‹‰ ์ง€๊ฐ‘ ์‚ฌ์šฉ์œผ๋กœ ์ธํ•ด @truffle/hdwallet-provider ์„ค์น˜ ํ•„์š”
npm install @truffle/hdwallet-provider
  • ๋„คํŠธ์›Œํฌ ์ˆ˜์ •
const HDWalletProvider = require("@truffle/hdwallet-provider");
const infuraKey = "YOUR INFURA KEY";

const fs = require("fs");
const mnemonic = fs.readFileSync(".secret").toString().trim();

2. truffle์ด์šฉํ•˜์—ฌ ๋ฐฐํฌ

3. ๋ฐฐํฌํ›„ truffle console ์‹คํ–‰ํ•˜์—ฌ mintNFTํ•จ์ˆ˜๋กœ NFT๋ฐœํ–‰

Transaction Hash: 0x92a1325b955d26509d24f16421a1f5ce23e78e2f904f72ec6f0d583ddb9add70


๐Ÿ“Œ ๊ฐœ๋ฐœํšŒ๊ณ 

KEEP

์ง์ ‘ ๊ฐœ๋ฐœ์„ ํ•˜๋ฉด ์ข‹์€์ ์ด ์ด๋ก ์œผ๋กœ ์•Œ์•˜์„๋•Œ์™€ ๋น„๊ตํ•ด์„œ ๋ชธ์— ๋ฐฐ๋Š” ์ง€์‹๋“ค์ด ์ƒ๊ธด๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด๋ฒˆ์—๋„ ์ด๋ก ์œผ๋กœ ๊ธฐ๋ณธ์„ ์ต์ธ ํ›„ ์ง์ ‘ ganache์™€ ropsten์„ ํ†ตํ•ด ๋ฐฐํฌ๋ฅผ ํ•ด๋ดค๋Š”๋ฐ, MyNFTs์ปจํŠธ๋ž™ํŠธ์—์„œ mintNFTํ•จ์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ์„ฑ์ด ๋˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  mintNFT์— ๋“ค์–ด๊ฐ€๋Š” tokenURI๋Š” ์–ด๋–ป๊ฒŒ ์ƒ์„ฑํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ข‹์€ ํ•™์Šต์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
NFT๋ฅผ ์ง์ ‘ ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ IPFS๋ผ๋Š” ๋‹ค๋ฅธ ๋ถ„์‚ฐ ์ €์žฅ์†Œ์— ์ €์žฅํ•˜๊ณ  ๊ทธ ์ด๋ฏธ์ง€์— ๋Œ€ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋˜ํ•œ ์ €์žฅํ•˜์—ฌ ๊ทธ URI๋ฅผ ๊ฐ€์ ธ๋‹ค ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ NFT๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ถ€๋ถ„์ด ์ด๋ฒˆ ํ•™์Šต์— ๊ฐ€์žฅ ํฐ ๋ฐฐ์›€์ด ์•„๋‹ˆ์—ˆ๋‚˜ ์‹ถ์Šต๋‹ˆ๋‹ค.

PROBLEM

๋ฐฐํฌํ•˜๊ณ ์„  ์ˆ˜์ •ํ•˜์—ฌ ์žฌ๋ฐฐํฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋ง‰์•„์ ธ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ์ž˜ ํ™•์ธํ•˜์—ฌ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ๋‹ค ๋ฐ€๊ณ  ๋‹ค์‹œ ๋ฐฐํฌํ•˜๋Š” ์ผ์ด ์—†๊ฒŒ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

TRY

  1. ์˜คํ”ˆ์”จ ํ…Œ์ŠคํŠธ๋„ท์—๋„ ๋ฐฐํฌํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋„ท์— NFT๊ฐ€ ์ž˜ ์˜ฌ๋ผ์˜ค๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.
  2. ์—ฌ๊ธฐ์„œ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ  ๋‹ค์Œ์—๋Š” ํ˜„์žฌ ํ•ซ๐Ÿ”ฅํ•œ ๋žœ๋คNFT์— ๋Œ€ํ•ด ๊ฐœ๋ฐœํ•ด๋ณด๊ณ  ํšŒ๊ณ ๋ก์„ ์ž‘์„ฑ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.
profile
MAKE SOMETHING

0๊ฐœ์˜ ๋Œ“๊ธ€