Truffle은 이더리움 솔리디티로 제작된 스마트 컨트랙트를 컴파일, 테스트, 배포(Migrate) 할 수 있는 프레임 워크 입니다. Truffle에서 컴파일을 진행하면, ABI와 Bytecode 등 컨트랙트를 사용할 수 있는 코드가 작성되고 이를 메인넷이나 테스트넷 혹은 로컬 블록체인 네트워크에 배포하여 사용할 수 있습니다.
로컬 환경에 Truffle로 컴파일 한 컨트랙트 배포하기
Truffle Ropsten TestNet 준비
1. Truffle 프로젝트를 초기화 합니다.
$ truffle init
NPM을 초기화 해줍니다.
$ npm init
프로젝트 구성이 완성됩니다.
.
├── contracts
│ └── Migrations.sol
├── migrations
│ └── 1_initial_migration.js
├── package.json
├── test
└── truffle-config.js
3 directories, 4 files
2. Infura에서 Ropsten Testnet 엔드포인트를 받아옵니다.
Infura에서 제공하는 API키를 붙인 엔드포인트는 다음과 같습니다.
https://ropsten.infura.io/v3/{Infura API Key}
3. Truffle에 니모닉 HD지갑을 연결해줄 모듈을 설치합니다.
$ npm install --save-dev @truffle/hdwallet-provider
4. truffle ropsten network 설정
truffle-config.js 파일안에 Truffle이 연결될 네트워크 설정을 해줍니다.
우선 아래 코드의 주석을 풀어줍니다.
이 코드에서 지갑의 비밀키를 저장할 ".secret" 파일을 생성한 후 메타마스크에 등록된 지갑의 비밀키를 적습니다.
const HDWalletProvider = require('@truffle/hdwallet-provider');
const fs = require('fs');
const mnemonic = fs.readFileSync(".secret").toString().trim();
메타마스크 지갑 비밀키 가져오기
메타마스크 접속 후 계정 세부 정보로 들어갑니다.
비공개 키 내보내기를 클릭합니다.
메타마스크 지갑 패스워드를 입력하면 비밀키를 가져올 수 있습니다.
5. truffle ropsten config 설정
다음으로 ropsten 네트워크 코드의 주석을 풀어줍니다. provider에 Infura에서 받은 API키를 작성합니다.
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 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 )
},
마지막으로 스마트 컨트랙트에 들어간 컴파일 버전을 맞춰줍니다.
저의 경우는 0.8.7 버전으로 컴파일을 진행합니다.
compilers: {
solc: {
version: "0.8.7", // 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"
// }
}
},
6. Ropsten 네트워크에 접속합니다.
$ truffle console --network ropsten
정상적으로 접속 완료되면 콘솔창이 출력됩니다.
truffle(ropsten)>
Truffle Ropsten TestNet 컴파일 및 배포
1. 배포할 스마트 컨트랙트를 작성합니다.
renderHelloWord() 1개의 함수를 가진 컨트랙트입니다.
함수 출력값으로 "Hello World" 문자열을 출력합니다.
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract HelloWorld {
function renderHelloWorld () public returns (string memory){
return "Hello World!";
}
}
2. migrations/01_initial_migrations.js 파일을 수정합니다.
이 파일에서는 배포할 컨트랙트를 지정해줍니다.
const HelloWorld = artifacts.require("HelloWorld");
module.exports = function (deployer) {
deployer.deploy(HelloWorld);
};
3. truffle ropsten deploy
Truffle에서 작성하고 테스트 한 컨트랙트를 컴파일 후 배포 합니다.
$ truffle migrate --compile-all --network ropsten
컴파일 및 배포가 시작됩니다.
Compiling your contracts...
===========================
> Compiling ./contracts/HelloWorld.sol
> Compilation warnings encountered:
Warning: Function state mutability can be restricted to pure
--> project:/contracts/HelloWorld.sol:5:5:
|
5 | function renderHelloWorld () public returns (string memory){
| ^ (Relevant source part starts here and spans across multiple lines).
> Artifacts written to /home/01_truffle_ropsten/build/contracts
> Compiled successfully using:
- solc: 0.8.7+commit.e28d00a7.Emscripten.clang
Starting migrations...
======================
> Network name: 'ropsten'
> Network id: 3
> Block gas limit: 30000000 (0x1c9c380)
1_initial_migration.js
======================
Deploying 'HelloWorld'
----------------------
> transaction hash: 0x7527a66130259f696e4f195f69247c5aa9fe581d873fef69232474d10973fa1f
> Blocks: 2 Seconds: 17
> contract address: 0x004328F93826551b46De347F0941dC773317a121
> block number: 12769794
> block timestamp: 1660269900
> account: 0xEFAb267AE6deb0d88576283Abc145f14DCAFDf79
> balance: 14.833135925789534113
> gas used: 135079 (0x20fa7)
> gas price: 2.500000007 gwei
> value sent: 0 ETH
> total cost: 0.000337697500945553 ETH
Pausing for 2 confirmations...
-------------------------------
> confirmation number: 1 (block: 12769795)
> confirmation number: 2 (block: 12769796)
> Saving artifacts
-------------------------------------
> Total cost: 0.000337697500945553 ETH
Summary
=======
> Total deployments: 1
> Final cost: 0.000337697500945553 ETH
배포가 완료 된 후 ropsten etherscan으로 접속해 확인하면, 아직 Verify and Publish가 안된 것을 확인할 수 있습니다.
4. 배포가 된 컨트랙트를 Verify & Publish합니다.
이더스캔에서 직접 Verify & Publish 해도 되지만 Truffle에서 지원하는 truffle-plugin-verify 모듈을 사용합니다. 개발환경에서만 사용하므로 -D 옵션을 삽입합니다.
$ npm -i -D truffle-plugin-verify
truffle-config.js 파일에서 plugin 관련 옵션을 기재합니다.
api key도 입력합니다.
ropsten: {
provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/7ea55eb19f3c4887a39e9f078d47f212`),
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 )
},
//
// 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)
// }
},
// truffle-plugin-verify module
plugins:[
'truffle-plugin-verify'
],
api_keys:{
etherscan : 'Etherscan API Key'
},
Truffle에서 verify를 진행합니다.
$ truffle run verify HelloWorld --network ropsten
Verify가 완료되면 아래 문구가 출력됩니다.
Verifying HelloWorld
Pass - Verified: https://ropsten.etherscan.io/address/0x004328F93826551b46De347F0941dC773317a121#code
Successfully verified 1 contract(s).
Ropsten 이더스캔에서 정상적으로 컨트랙트 배포 + Verify까지 진행완료입니다.
Reference
- https://www.npmjs.com/package/truffle-plugin-verify
- https://forum.openzeppelin.com/t/how-to-verify-with-hardhat-or-truffle-a-smart-contract-using-openzeppelin-contracts/4119
'Blockchain' 카테고리의 다른 글
Truffle Testing 방법 (Mocha, chai 사용) (1) | 2022.08.20 |
---|---|
Truffle develop account 확인 (기본 사용 방법) (1) | 2022.08.20 |
[회고록] 첫번째 프로젝트(Opensea) 시작 (0) | 2022.08.08 |
[Blockchain] 이더스캔 서비스 구축하기 (0) | 2022.08.04 |
[Blockchain] getTransactionsByAccount() 함수 구현하기 (0) | 2022.08.04 |
댓글