반업주부의 일상 배움사
[블록체인/NFT] 이미지 생성부터 오픈씨까지 (Rinkeby/Ethereum) 본문
이미지 생성 등은 이전 글에서 참고할 수 있어요.
2022.04.30 - [IT 인터넷/일반] - [NFT] 이미지 생성부터 오픈씨까지 (Mumbai/Polygon)
새 폴더를 만들고 터미널을 연 다음 아래 코드를 실행해요.
$ npm init -y
$ npm install -g truffle
$ npm audit fix --force
$ npm i --save @truffle/hdwallet-provider
$ npx truffle init
Ganache를 설치할께요.
https://trufflesuite.com/ganache/
Ganache 실행 > NEW WORKSPACE > 이름 입력 > ADD PROJECT > 프로젝트 폴더의 truffle-config.js 선택
Server 탭 선택 > PORT NUMBER 복사 > truffle-config.js의 아래 코드 주석을 풀고 port 변경
Ganache > SAVE WORKSPACE 클릭
// development: {
// host: "127.0.0.1", // Localhost (default: none)
// port: 8545, // Standard Ethereum port (default: none)
// network_id: "*", // Any network (default: none)
// },
위 코드의 port 변경
development: {
host: '127.0.0.1', // Localhost (default: none)
port: 7545, // Standard Ethereum port (default: none)
network_id: '*', // Any network (default: none)
},
터미널에서 아래 코드 실행.
$ npm install --save @openzeppelin/contracts
프로젝트 > contracts 폴더에 Banjubu.sol 파일 생성.
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract Banjubu is Ownable, ERC721 {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
using Strings for uint256;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
// Base URI
string private _baseURIextended;
constructor() public ERC721("banjubu", "BANJB") {}
// https://forum.openzeppelin.com/t/function-settokenuri-in-erc721-is-gone-with-pragma-0-8-0/5978/3
function setBaseURI(string memory baseURI_) external onlyOwner {
_baseURIextended = baseURI_;
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI)
internal
virtual
{
require(
_exists(tokenId),
"ERC721Metadata: URI set of nonexistent token"
);
_tokenURIs[tokenId] = _tokenURI;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseURIextended;
}
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
function claimItem(string memory tokenURI) public returns (uint256) {
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_safeMint(msg.sender, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
function totalSupply() public view returns (uint256) {
return _tokenIds.current();
}
}
프로젝트 > migrations 폴더에 '2_deploy_banjubu.js' 파일 생성.
const banjubu = artifacts.require('banjubu');
module.exports = function (deployer) {
deployer.deploy(banjubu);
};
터미널에서 아래 코드 실행.
$ npm i --save solc
$ npx solc --version
0.8.13+commit.abaa5c0e.Emscripten.clang
이렇게 나오면 0.8.13 복사 > 프로젝트 > truffle-config.js > compilers 아래 solc의 version 주석 풀고 붙여넣기.
compilers: {
solc: {
version: '0.8.13', // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: {
// enabled: false,
// runs: 200
// },
// evmVersion: "byzantium"
// }
},
},
터미널에서 아래 코드 실행.
$ npx truffle console
콘솔 실행
truffle(development)> $ migrate
완료 후 확인
truffle(development)> $ let banjubu = await Banjubu.deployed()
truffle(development)> $ banjubu.address
truffle(development)> $ accounts[0]
가입 > 프로젝트 생성 > ENDPOINTS를 RINKEBY로 변경 > URL 복사 > truffle-config.js > clientURL에 설정
메타마스크 > Private Key 복사 > truffle-config.js > mnemonic에 설정
truffle-config.js
/**
* Use this file to configure your truffle project. It's seeded with some
* common settings for different networks and features like migrations,
* compilation and testing. Uncomment the ones you need or modify
* them to suit your project as necessary.
*
* More information about configuration can be found at:
*
* trufflesuite.com/docs/advanced/configuration
*
* To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
* to sign your transactions before they're sent to a remote public node. Infura accounts
* are available for free at: infura.io/register.
*
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
* public/private key pairs. If you're publishing your code to GitHub make sure you load this
* phrase from a file you've .gitignored so it doesn't accidentally become public.
*
*/
const HDWalletProvider = require('@truffle/hdwallet-provider');
const mnemonic = ``; // metamask private key
const clientURL = `https://rinkeby.infura.io/v3/...`;
// const HDWalletProvider = require('@truffle/hdwallet-provider');
// const infuraKey = "fj4jll3k.....";
//
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();
module.exports = {
/**
* Networks define how you connect to your ethereum client and let you set the
* defaults web3 uses to send transactions. If you don't specify one truffle
* will spin up a development blockchain for you on port 9545 when you
* run `develop` or `test`. You can ask a truffle command to use a specific
* network from the command line, e.g
*
* $ truffle test --network <network-name>
*/
networks: {
// Useful for testing. The `development` name is special - truffle uses it by default
// if it's defined here and no other network is specified at the command line.
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
// tab if you use this network and you must also set the `host`, `port` and `network_id`
// options below to some value.
//
development: {
host: '127.0.0.1', // Localhost (default: none)
port: 7545, // Standard Ethereum port (default: none)
network_id: '*', // Any network (default: none)
},
// Another network with more advanced options...
// advanced: {
// port: 8777, // Custom port
// network_id: 1342, // Custom network
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
// from: <address>, // Account to send txs from (default: accounts[0])
// websocket: true // Enable EventEmitter interface for web3 (default: false)
// },
// Useful for deploying to a public network.
// NB: It's important to wrap the provider as a function.
// ropsten: {
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
// network_id: 3, // Ropsten's id
// gas: 5500000, // Ropsten has a lower block limit than mainnet
// confirmations: 2, // # of confs 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 )
// },
// Useful for private networks
// private: {
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
// network_id: 2111, // This network is yours, in the cloud.
// production: true // Treats this network as if it was a public net. (default: false)
// }
rinkeby: {
provider: () => new HDWalletProvider(mnemonic, clientURL),
network_id: 4, // Rinkeby's id
gas: 3000000,
confirmations: 2, // # of confs 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 )
networkCheckTimeout: 10000000,
},
},
// Set default mocha options here, use special reporters etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: '0.8.13', // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: {
// enabled: false,
// runs: 200
// },
// evmVersion: "byzantium"
// }
},
},
};
터미널에서 아래 코드 실행.
$ npx truffle console --network rinkeby
truffle(rinkeby)> $ migrate
truffle(rinkeby)> $ const banjubu = await Banjubu.deployed()
truffle(rinkeby)> $ await banjubu.claimItem('https://ipfs.io/ipfs/[CID]')
메타마스크 주소로 NFT가 발행되었네요.
출처: https://github.com/neha01/nft-demo
영어, 중국어 공부중이신가요?
홈스쿨 교재. 한 권으로 가족 모두 할 수 있어요!
'IT 인터넷 > Blockchain' 카테고리의 다른 글
메타마스크에 폴리곤 테스트넷(Mumbai) 추가 :: Metamask Polygon Testnet (0) | 2022.07.29 |
---|---|
블록체인 하나씩 알아보기 :: Market (0) | 2022.07.20 |
블록체인 하나씩 알아보기 :: ERC721 (0) | 2022.07.19 |
블록체인 하나씩 알아보기 :: ERC20 (0) | 2022.07.19 |
[블록체인/NFT] 이미지 생성부터 오픈씨까지 (Mumbai/Polygon) (0) | 2022.04.30 |