Truffle๋ก ERC 721 ๊ฐ๋ฐ
Truffle๋ก ERC 721 ๊ฐ๋ฐ
๐ง๐ป๐ป ๊ฐ๋ฐ ๋ชฉํ
Truffle์ ์ด์ฉํด์ ERC-721์ ๊ฐ๋ฐํ๋ค. Openzeppelin ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๊ณ ๋ฉ์ธ๋ท์ด ์๋๋ผ ๊ฐ์ํ๊ฒฝ์์ ํ ์คํธํ๊ธฐ ์ํด Ganache๋ฅผ ์ฌ์ฉํ๋ค. CLI๋ ํ ๋ฒ๋ ์ฌ์ฉํด๋ณธ์ ์๊ธฐ ๋๋ฌธ์ ์ผ๋ถ๋ฌ Ganache-cli๋ฅผ ์ฌ์ฉํ๋ค.
ERC-721๋?
ERC-20๊ฐ์ ๋์ฒด ๊ฐ๋ฅ(fungible)ํ ํฐ๊ณผ ๋ค๋ฅด๊ฒ ERC721์ ๋์ฒดํ ์ ์๋(non-fungible) ํ ํฐ ํ์ค์ด๋ค. NFT๋ ๋ธ๋ก์ฒด์ธ ํ๋ซํผ์์ ๋์งํธ ์๋ช ์ ๊ธฐ๋ฐ์ผ๋ก ํ ์์ ๊ถ์ ์ธ์ ๋ฐ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค. ERC721 ํ์ค์ ์ฆ์์ ์ํด ๊ทธ ์์ ๊ถ์ด ๊ณ ์ ํ๊ฒ ์ถ์ ๋ ์ ์๋ ํ, ๊ทธ ๋์์ ์ข ๋ฅ์ ๋ํด ์ด๋ค ์ ํ์ด๋ ๊ท์ ์ ๋์ง ์์ผ๋ฉด, ์ด๋ฌํ ์ถ์ ์ 256๋นํธ ์๋ณ์์ ์ํด ์ด๋ฃจ์ด์ง๋ค.
Truffle?
์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ๊ฐ๋ฐ ํ ๋ ๊ฐ๋ฐ ๋ฐ ํ ์คํธ, ๋ฐฐํฌํ๊ฒฝ์ ์ ๊ณตํด์ฃผ๋ ํ๋ ์์ํฌ
OpenZeppelin ?
์ค๋งํธ ์ปจํธ๋ํธ ๊ฐ๋ฐ์ ๋์์ ์ฃผ๋ ํ๋ ์์ํฌ
Ganacahe ?
์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ๋ก์ปฌ ํ๊ฒฝ์์ ํ ์คํธ ํ ์ ์๊ฒ ๋์์ค
๐จ ๊ฐ๋ฐ๊ณผ์
๊ฐ๋ฐ ํ๊ฒฝ ์ธํ
truffle ์ค์น
npm install -g truffle
ํ๋ก์ ํธ ์ด๊ธฐํ
truffle init
npm init
ganache ์ค์น
npm install -g ganache-cli
์คํ์ ํ๋ฆฐ ์ค์น
npm install @openzeppelin/contracts
ํ๋ก์ ํธ ๋๋ ํ ๋ฆฌ ๊ตฌ์ฑ
- Contracts : smart contract ์์ค ( *.sol)
- migrations : ๋ฐฐํฌ์ ํ์ํ ํ์ผ
- test : smart contract ํ ์คํธ๋ฅผ ์ํ ํด๋
- truffle-config.js : truffle ์ ํ ํ์ผ
truffle-config.js
networks: {
ganache: {
host : '127.0.0.1', // local
port : 8545,
network_id: '*',
},
compilers: {
solc: {
version: '0.8.7',
evmVersion: 'london',
},
},
network ์ ๋ณด ์ถ๊ฐ (port 8545๋ ganache-cli)
*.sol ํ์ผ๊ณผ solidity version์ ์ผ์น์์ผ์ค๋ค.
contracts/MyNFTs.sol
// 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;
}
}
์คํ์ ํ๋ฆฐ์ Ownable, ERC721URIStorage๋ฅผ ์ฌ์ฉํ๋ค.
migration/1_initial_migration.js
const Migrations = artifacts.require("Migrations");
const MyNFTs = artifacts.require('MyNFTs')
module.exports = function (deployer) {
deployer.deploy(Migrations);
deployer.deploy(MyNFTs);
};
ganache-cli
truffle migrate —compile-all —network ganache
ganache cli๋ฅผ ์ด๊ณ ๊ฐ๋์์ ์ฐ๊ฒฐํด์ ๋ชจ๋ ์ปจํธ๋ํธ๋ฅผ ๋ฐฐํฌ
ganache-cli ์คํ์ฑ๊ณต ํ๋ฉด
truffle console —network ganache
truffle console ์คํ
๋ฐฐํฌํ ์ปจํธ๋ํธ์ ์ธ์คํด์ค ๋ฐ๊ณ ํ์ธ
mintNFT ํจ์ ์คํํ์ฌ NFT ๋ฐํ
๋ฐํํ tokenURIํ์ธ
๐ฅ Ropsten Testnet์ ๋ฐฐํฌํด๋ณด๊ธฐ
HDWalletProvider, dotenv ์ค์นํจ
npm i dotenv
npm i --save truffle-hdwallet-provider
.envํ์ผ์ ์์ฑํ๊ณ MNEMONIC์ ๋๋ชจ๋์ฝ๋๋ฅผ, INFURA_ENDPOINT์ ropsten network ์๋ํฌ์ธํธ๋ฅผ ์ถ๊ฐํ๋ค.
๐ซต github์ ์ฌ๋ฆด๋๋ ๊ผญ .gitignore๋ก .envํ์ผ์ ์ ์ธ์์ผ ์ค ๊ฒ(๋๋ชจ๋ ์ฝ๋ ๋ฑ์ ๊ณต์ ๋๋ฉด ์ ๋จ)
truffle-config.js
var HDWalletProvider = require("truffle-hdwallet-provider");
require('dotenv').config()
const mnemonic = process.env.MNEMONIC
const infuraEndpoint = process.env.INFURA_ENDPOINT
ropsten: {
provider: () => new HDWalletProvider(mnemonic, infuraEndpoint),
network_id: 3, // Ropsten's id
gas: 5500000, // Ropsten has a lower block limit than mainnet
// confirmations: 2, // # of confirmations to wait between deployments. (default: 0)
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
},
ropsten network๋ฅผ ์ถ๊ฐํ๋ค.
Truffle๋ก ๋ฐฐํฌ
> truffle deploy --network ropsten
> truffle console --network ropsten
truffle console์ ์ผ ๋ค mintNFT ํจ์ ์ฌ์ฉํด์ NFT๋ฐํ
Etherscan Transaction Details
https://ropsten.etherscan.io/tx/0xa9b45b62b6437fd8054db942c80ebc674b683b06572c444f485368af868af294
Ropsten Transaction Hash (Txhash) Details | Etherscan
Ropsten (ETH) detailed transaction info for txhash 0xa9b45b62b6437fd8054db942c80ebc674b683b06572c444f485368af868af294. The transaction status, block confirmation, gas fee, Ether (ETH), and token transfer are shown.
ropsten.etherscan.io
Transaction hash : 0xa9b45b62b6437fd8054db942c80ebc674b683b06572c444f485368af868af294
https://ropsten.etherscan.io/address/0x1ae0ce7fffd7fb058a5690fa6d1014f177e4219c
Contract Address 0x1ae0ce7fffd7fb058a5690fa6d1014f177e4219c | Etherscan
The Contract Address 0x1ae0ce7fffd7fb058a5690fa6d1014f177e4219c page allows users to view the source code, transactions, balances, and analytics for the contract address. Users can also interact and make transactions to the contract directly on Etherscan.
ropsten.etherscan.io
Contract Hash : 0x1AE0ce7FfFD7FB058A5690Fa6D1014F177E4219C
๐ ๊ฐ๋ฐ ํ๊ณ
Keep
ERC-721 ๊ฐ๋ ๊ณผ Truffle, Ganache์ ๋ํด์ ๋ค์ ํ ๋ฒ ๊ณต๋ถํ๋ค. ํนํ Ganache-cli๋ฅผ ์ฌ์ฉํด ๋ณธ ์ ์ด ์ ์ตํ๋ค. Ropsten Network์ ์ง์ ๋ฐฐํฌํด๋ณด๋ ๊ฒ๋ ์ข์ ๊ฒฝํ์ด์๋ค.
Problem
๋จ์ํ ํจ์๋ง ํ์ฉํด๋ด์ ์์ง ์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ์์ ์์ฌ๋ก ๋ค๋ฃจ์ง ๋ชปํ๋ ๊ฒ ๊ฐ๋ค.
Try
๋ค์ํ ์ค๋งํธ ์ปจํธ๋ํธ ๊ธฐ๋ฅ์ ๋ํด์ ๊ณต๋ถํ๊ณ ์ค์ตํด ๋ด์ผ๊ฒ ๋ค. ์ถํ์ ERC-721 ๊ด๋ จ ํ๋ก์ ํธ๋ฅผ ํ๋ฉด
๐ Github Repo
https://github.com/jongseokleedev/truffle_ERC721
GitHub - jongseokleedev/truffle_ERC721
Contribute to jongseokleedev/truffle_ERC721 development by creating an account on GitHub.
github.com