Development of ERC-721 using Truffle
ERC-20이 '대체 가능'한 토큰을 발행한다면 ERC-721은 '대체 불가능'한 토큰을 발행한다. 오늘은 ERC-721을 사용해 NFT를 발행하는 실습을 진행한다.
GitHub, Etherscan(smart contract)
github repository
smart contract
개발환경
truffle, opensea testnet, etherscan rinkeby, pinata
테스트 네트워크 설정
truffle-config.js
파일에서 몇가지 설정이 필요하다.
1. solc
작성할 컨트랙트의 솔리디티, 컴파일 버전을 확인 후 수정한다. "0.8.7", "london"
compilers: {
solc: {
version: "0.8.7",
evmVersion: "london",
},
},
HDWalletProvider
const HDWalletProvider = require("@truffle/hdwallet-provider");
const fs = require("fs");
const mnemonic = fs.readFileSync(".secret").toString().trim();
.secret
파일을 만들어 mnemonic 키를 담아준다.
추가적으로 .gitignore
에 .secret
파일을 작성해야 github repository에 .secret
파일이 올라가지 않는다.
networks
: rinkeby 사용을 위해 기존 ropsten으로 작성된 부분을 주석해제 후 변경해준다. 참고
rinkeby: {
provider: () =>
new HDWalletProvider(
mnemonic,
`https://rinkeby.infura.io/v3/{infura에서 받은 api key}`, 1), // 3번째 인자는 메타마스크 계정의 인덱스이다.
network_id: 4, // Rinkeby's id
gas: 4500000,
gasPrice: 10000000000,
confirmations: 2,
timeoutBlocks: 200,
skipDryRun: true,
},
smart contract 작성
vs code에 MyNFTs.sol
파일을 만들어 아래 코드를 작성한다. openzeppelin 라이브러리를 사용하기 때문에 추가적으로 설치가 필요하다.
npm install @openzeppelin/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("MyNFTs", "MNFT") {}
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;
}
}
migration 파일 설정
컨트랙트 배포를 위해 migration 파일 설정이 필요하다.
migration
폴더 아래 기존 파일인 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); // 추가
};
smart contract 컴파일, 배포
오픈씨 테스트넷에 NFT를 올리기 위해 network는 rinkeby를 사용한다. 터미널에서 다음 명령어를 작성하면 컴파일 후 배포까지 이루어진다.
truffle migrate --compile-all --network rinkeby
터미널에서 컴파일 후 배포까지 진행되는 모습을 확인할 수 있다.
MyNFTs의 transaction hash를 복사해 이더스캔에서 검색해보면 아래처럼 확인이 가능하다.
contract verify & publish
contract verify&publish를 진행하면 이더스캔에서 함수를 작동시킬 수 있다. 방금 확인한 transaction에서 contract주소를 클릭하면 아래와 같이 나온다.
contract 부분을 클릭하여 verify를 진행한다.
contract code를 작성할 때 truffle-flattener를 사용해 import했던 openzeppelin의 코드를 전부 넣어주어야 한다. 다시 vs code로 돌아가 flat
폴더를 만들고 터미널에 다음 명령어를 순차적으로 입력한다.
npm install truffle-flattener --save
truffle-flattener ./contracts/MyNFTs.sol > ./flat/MyNFTs.sol
flat
폴더의 MyNFTs.sol
을 확인하면 openzeppelin의 모든 코드가 들어와 있다. 전체 코드를 복사해서 다시 이더스캔의 verify를 진행하면 된다.
그러나 복사한 소스코드를 입력해도 에러가 발생했다.
truffle-flattener를 사용했더니 SPDX 부분이 중복으로 들어가 생긴 문제였다. sol-merger를 사용하면 중복되는 SPDX를 알아서 제거해준다고 했지만 적용이 되지 않아 수동으로 중복된 부분을 제거했다.
verify & publish가 완료되면 이더스캔에서 함수를 실행할 수 있다. 다음 작업을 통해 mintNFT함수를 사용해 NFT를 발행해볼 수 있다.
metadata file 생성
mintNFT함수에는 두 가지 인자가 들어간다. 첫 번째는 NFT를 받는 사람의 주소이고, 두 번째는 tokenURI이다. 여기서는 tokenUI 생성 작업을 진행한다.
우선 vs code로 돌아가 test.json
파일을 만들어준다. 그리고 아래와 같이 입력한다.
{
"name": "Loyal Duck #001",
"description": "Made on December 18, 2021",
"image": "https://imagedelivery.net/v7-TZByhOiJbNM9RaUdzSA/2c6f93b0-891f-42b4-a017-bcf85c03cb00/public",
"attributes": [
{
"trait_type": "TYPE",
"value": "Cute"
}
]
}
이후 생성한 json 파일을 pinata에 업로드시킨다. 이전 실습에서는 nft.storage를 사용했으나 storage providers가 정해지는데 48시간이 걸려서 대신 피나타를 사용했다.
파일 업로드 후 CID 부분을 복사한다.
mintNFT
이더스캔으로 돌아와 mintNFT를 마저 진행한다.
첫 번째 인자(recipient)에 NFT를 받을 주소를 입력하고 두 번째 인자(tokenURI)에 피나타에서 받아온 CID를 입력 후 Write
를 클릭 후 가스비를 결제한다.
OpenSea Testnets
앞서 mintNFT함수를 실행해 NFT를 발행했다. 확인을 위해
오픈씨 테스트넷으로 이동한다. 아래 동작영상으로 확인이 가능하다.
metadata로 작성된 속성들이 오픈씨 테스트넷에서 잘 보이고 있다.
개발 회고 (KPT)
KEEP(작업 및 코드적으로 좋았던 경험)
예전 실습 때 미뤄둔 부분들이 많았는데 이번 실습을 통해 거의 모든 부분들을 해결해볼 수 있어 매우 유익했다. 특히 네트워크 환경을 ganache에서 rinkeby로 변경해 설정하다보니 지갑 설정 및 가스비 오류 가 있었는데 이런 오류들을 해결하는 과정이 재밌었다. metadata를 직접 작성하는 부분도 NFT가 만들어진 과정을 더 구체하게 볼 수 있어 좋았던 부분이다. 개인적으로 NFT 발행이 가장 즐거운 작업이었다.
PROBLEM(작업 및 코드에서 좋지 않았던 경험)
작업하며 블로그를 동시에 작성하는 편이 좋았을 것 같다. 모든 작업이 끝나고 정리하니 작업보다 더 많은 시간을 블로깅에 할애했다.
TRY(앞으로 시도해볼 액션 아이템 설정)
현재는 함수를 한번 실행할 때 하나의 NFT를 발행하고 있다. 그러나 NFT를 다량으로 발행하는 작업이 가능하다고 하여 추가적으로 학습 후 NFT를 다량으로 발행하는 코드를 작성해 보고 싶다.
Author And Source
이 문제에 관하여(Development of ERC-721 using Truffle), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@journiyoon/Development-of-ERC-721-using-Truffle저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)