유사한 가이드들
환경
라즈베리파이 콘솔에서 진행(nodejs는 12.22.7 버전, truffle은 5.1.67버전으로 설치함)
1. nodejs 설치(sudo apt-get install nodejs npm)
- truffle포함 대부분 이더리움 배포환경은 node js기반으로 작성되어 있기 때문에 필요
2. infura.io 설정(웹사이트 가입 및 WEB3 API KEY설정)
- 비트코인과 마찬가지로 이더리움도 분산화된 노드 기반으로 동작하는데, 원래는 ERC-20을 이 노드에 올려야 한다.
- (이더리움 노드는 비트코인 노드와 다르게 EVM을 구동하고 바이트코인을 돌리는 가상 컴퓨터역할도 한다. 스마트계약은 모든 노드에서 반복수행되며 같은 결과가 나오는지 검증된다. 이에 따라 결정론성이 중요한데, 이는 나중에 후술하기로 하자)
- 하지만 노드 운용에는 전체 블록체인을 다운받아야 하기도 하고, 복잡하고 무거운 컴퓨팅 설정이 필요하다.
- infura는 이러한 개인이 노드운용을 해야하는 부담을 대신해주며, 가볍게 스마트계약을 배포할 수 있다.
3. truffle 설치(npm install -g truffle)
- 원래 스마트계약 solidity 파일은 solc로 컴파일 하는데, truffle을 사용하면 컴파일부터 테스트, 마이그레이션까지 원툴로 전과정 제공
- 설치후 truffle init을 해주면 기본 폴더나 config파일(truffle-config.js) 만들어준다.
- truffle-config.js는 아래처럼 작성
- 복잡해 보이지만 development는 로컬 환경, sepolia는 테스트넷 환경을 위한거
require('dotenv').config();
const { MNEMONIC, PROJECT_ID } = process.env;
const HDWalletProvider = require('@truffle/hdwallet-provider');
module.exports = {
networks: {
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 8545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
gas: 30000000,
},
sepolia: {
//provider: () => new HDWalletProvider(MNEMONIC, `https://sepolia.infura.io/v3/${PROJECT_ID}`),
provider: () => new HDWalletProvider(MNEMONIC, `wss://sepolia.infura.io/ws/v3/${PROJECT_ID}`),
network_id: 11155111,
gas: 4465030,
networkCheckTimeout: 100000,
},
},
// Set default mocha options here, use special reporters, etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: "0.8.19", // 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"
// }
}
},
};
4. openzeppelin 설치(npm install @openzeppelin/contracts)
- 스마트계약을 처음부터 코딩하지 않도록 상속만 하면 되는 base 클래스(contract) 제공
5. 스마트 계약 solidity 파일 작성
- 아래 처럼 openzeppelin에서 제공하는 ERC20을 상속하면 만들기 쉽다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract SevityToken is ERC20 {
constructor(uint256 initialSupply) ERC20("Sevity Token", "SEVITY") {
_mint(msg.sender, initialSupply);
}
}
6. migrations 폴더에 다음 파일 작성
- 1_initial.js로 저장(사실 이름은 큰 상관 없고 숫자를 앞에 붙이면 그 순서대로 실행해준다)
- 아래는 스마트 계약을 테스트넷에 배포하면서 초기 발행량을 10억개로 하는 코드
const SevityContract = artifacts.require("SevityToken");
module.exports = function(deployer) {
const initialSupply = web3.utils.toWei('1000000000', 'ether'); // 10억 토큰
deployer.deploy(SevityContract, initialSupply);
};
7. sepolia넷에서 공짜로 ETH받기
- 메타마스크에서 메인넷 대신 sepolia테스트넷으로 설정하고(그냥 고르면 되는 수준이다)
- 테스트용 ETH는 https://sepoliafaucet.com/ 여기접속해서 받으면 된다(테스트용이라 공짜로 받을 수 있다)
8. 단순한 ERC-20제작 테스트이므로 로컬환경에 배포는 생략하고, 테스트넷중 하나인 sepolia에 배포(truffle migrate --network sepolia)
- 이때 contracts안에 있는 sevity_token.sol 컴파일
- migrations안에있는 스크립트들 수행된다.
9. 배포성공후 이더스캔에 가보면 다음처럼 Contract Creation 트랜잭션을 볼 수 있다.
10. 코인발행이후 스마트계약의 읽기 작업은 가스를 소모하지 않으며, 초기 발행량을 조회하려면 truffle로 다음처럼 할 수 있다.
(coin) sevity@raspberrypi:~/workspace/erc20 $ truffle console --network sepolia
truffle(sepolia)> let instance = await SevityToken.deployed()
undefined
truffle(sepolia)> let balanceInWei = await instance.balanceOf("0xFbb5164e8884ccB4893381b374D1ec8BbbC56F75")
undefined
truffle(sepolia)> let balanceInTokens = web3.utils.fromWei(balanceInWei.toString())
undefined
truffle(sepolia)> console.log(balanceInTokens)
1000000000
undefined
truffle(sepolia)>
11. 메타마스크에 커스텀 토큰으로 추가하기
- 아래처럼 계약주소(truffle migrate 과정에서 결과로 출력되며, 이더스캔에서도 확인가능)를 넣으면 토큰기호나 소수점은 알아서 세팅된다.
12. 메인넷에 배포
- truffle-config.js에 다음 부분 추가해주면 되는데
mainnet: {
provider: () => new HDWalletProvider(MNEMONIC, `wss://mainnet.infura.io/ws/v3/${PROJECT_ID}`),
network_id: 1,
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 )
gas: 21000,
gasPrice: 50000000000, // 50GWEI
networkCheckTimeout: 100000,
},
- gas와 gasPrice 부분은 설명이 좀 필요하다.
- gas는 gasLimit을 설정하는 부분인데, gas는 스마트계약 복잡성에 따라 런타임에 이러리움에서 정확하게 부여하게 되지만, 사전에 알수는 없다. 사전에 알기 힘든 이유는 정지문제(Halting Problem)때문인데 주어진 프로그램이 언제 멈출지, 또는 계속 실행될지를 모르기 때문이다. 요금은 실제 사용된 gas에 의해 부과되기에 gasLimit을 무조건 높은 값으로 해놓고 보는게 개발자에게는 유리할 수 있는데, 이더리움 블록마다 gasLimit 합계의 제한이 걸려있어서(80만 GWEI던가), 채굴자들이 블록하나 안에 많은 트랜잭션을 포함하기 위해 기피할 수 있다는 점이 있다. 그렇다고 너무 작은 값을 주었다가 실제 사용량이 그보다 크면 out of gas 오류가 나며 트랜잭션이 실패해 버리게 된다(단, 트랜잭션 실패시에도 사용된 gas는 환원되지 않고 gas 비용은 손실되므로 주의가 필요!!) 적절한 gasLimit을 대략적으로 계산해주는 툴도 있다고 하는데 아직 써보진 않았다.
- gasPrice는 이와 다르게, 개발자가 높게 책정할수록 그대로 채굴자의 이득이 되는데, 너무 낮으면 채굴이 진행이 잘 안고, 너무 높으면 손해이므로 어느 정도가 적절한지는 가스트래커를 통해 확인할 수 있다.
- 채굴자에게는 실제로 스마트계약 복잡성에 따라 사용된 gas * gasPrice를 보상으로 지급된다.
반응형
'비트코인' 카테고리의 다른 글
NFT (0) | 2023.06.24 |
---|---|
Solidity (0) | 2023.05.17 |
나만의 ERC-20 토큰 만들기 (0) | 2023.05.09 |
스마트 컨트랙트 (0) | 2023.03.15 |
유동성풀, LP공급, 비영구적 손실의 개념 (0) | 2023.03.14 |