이번에 Truffle을 이용한 솔리디티 프로그래밍을 볼 일이 있어 여기에 기록을 해 놓는다.

환경설정

OS : Ubuntu 20.04 LTS

Node : v14.19

  • 로컬 블록체인 개발용 서버인 가나슈를 설치한다.
$ sudo npm install -g ganache 
  • truffle을 설치한다.
$ sudo npm install -g truffle
  • truffle 프로젝트 구조를 만든다.
$ mkdir blockchainTest
$ cd blockchainTest
$ truffle init

만들어진 구조는 아래와 같다.

.
├── contracts
│   └── Migrations.sol
├── migrations
│   └── 1_initial_migration.js
├── test
└── truffle-config.js

이제 본격적인 파일 셋팅을 한다.

파일 셋팅

  • contracts 폴더에 Lottery.sol이라는 솔리디티 컨트렉트 파일을 아래와 같이 생성한다. 1
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract Lottery {
    address public owner;
}
  • 이 파일에 수행시킬 함수를 기입한다. 여기서는 테스트를 위해 getSomeValue()를 작성해 보겠다.
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract Lottery {
    address public owner;

    constructor(){
        owner = msg.sender;
    }
    function getSomeValue() public pure returns (uint256){
        //우리가 테스트할 함수. 
        return 5;
    }

}
  • 이 파일을 블록체인 서버(여기서는 가나슈 서버)로 마이그레이션 시킬 js파일을 migrations폴더에 새로 만들어 준다. 파일 이름은 2_deploy_lottery.js로 하겠다.
const Lottery = artifacts.require("Lottery");

module.exports = function (deployer) {
  deployer.deploy(Lottery);
};

빌드

  • 이제 컨트랙트 파일을 컴파일한다. 컴파일 명령은 아래와 같다.
$ truffle compile

Compiling your contracts...
===========================
> Compiling ./contracts/Lottery.sol
> Compiling ./contracts/Migrations.sol
> Artifacts written to /home/ubuntu/blockchainTest/build/contracts
> Compiled successfully using:
   - solc: 0.8.11+commit.d7f03943.Emscripten.clang
  • 컴파일 이후의 작업 폴더 구조는 아래와 같다. build디렉토리 내에 새로운 폴더 및 파일이 생성되었다.
.
├── build
│   └── contracts
│       ├── Lottery.json
│       └── Migrations.json
├── contracts
│   ├── Lottery.sol
│   └── Migrations.sol
├── migrations
│   ├── 1_initial_migration.js
│   └── 2_deploy_lottery.js
├── test
└── truffle-config.js

서버에 배포해보기

우리는 가나슈 로컬 서버를 띄우고 여기에 배포를 해 보겠다.

  • 먼저 가나슈 로컬 서버를 구동
$ ganache-cli

Ganache CLI v6.12.2 (ganache-core: 2.13.2)

Available Accounts
==================
(0) 0x3223E6492CA619a3aF219d36aA5ecAaCa914D1Eb (100 ETH)
(1) 0xEa1c6eEB72c2c7c09BC555625Bb08a38a38924a2 (100 ETH)
(2) 0xC61d1ddd851ba7d01a5f28F448A05191B8229741 (100 ETH)
(3) 0x73a8DE6D3d4299F0C7C00B93B36E8511ed2923f1 (100 ETH)
(4) 0xDa444f4dA9603417d70522ae7de4d43DA5031C13 (100 ETH)
(5) 0x267856291d5De1eB756bA274f1076035F24A991C (100 ETH)
(6) 0x45792a0f781936Ce8f6ECdDC4886CC15eE4833d3 (100 ETH)
(7) 0xc2CE71a5166411B54C5a115A6Ec72652dccA7473 (100 ETH)
(8) 0xe7FB4fD0dE9AB0C586eaaA960a25db2aF6744b84 (100 ETH)
(9) 0x3423b1f7027A6e936e35C761341C560E6e3569ed (100 ETH)

Private Keys
==================
(0) 0x95283dae9712fb038512a0738ac9a341e73deef23014d43421e544f69da2cc26
(1) 0xfea0acdf8231daf66ca153a87203db55719bd91e76edeb9ae810f42f9fd88b98
(2) 0xefbd2740fd7f03136e050980f1c734a400a5deab0385899767edcb73731cda82
(3) 0xc1d1de31aa5714c330f7c4e5f871f5f6d476a8a9eaec190a640e6aa4dc5f7f6c
(4) 0x06fd5bb4cee309a05b93616da5d93a52d06abb1e262e14f55a3bb77017c08cc1
(5) 0x3e5e9db0292ec75775d9e7e97922283b0e168c9c0a894545a848c4ed8082595c
(6) 0xe9fb40a3f43a34b5d98c5877e39010146be47884d365dcf5b6ace2345ff18cec
(7) 0x2241442a90c3340386a4aa158cc4471406dc334408f66b2b774ecc86171cb1e2
(8) 0x52b5289f832784d4b9562bbaaf027bf17718c023d41c0f6c7eabcc6a2a175bd3
(9) 0x062cbd7aba7dd715cab517ebb0ab6d539d19a18052a5d0412308743f9bca6f1a

HD Wallet
==================
Mnemonic:      elegant fall pink old crash review panther aware squirrel steel message choice
Base HD Path:  m/44'/60'/0'/0/{account_index}

Gas Price
==================
20000000000

Gas Limit
==================
6721975

Call Gas Limit
==================
9007199254740991

Listening on 127.0.0.1:8545

블록체인 서버관련 정보가 리스팅 되면 잘 띄운 것이다.

  • truffle-config.js 파일 수정

이 파일을 열어 network섹션의 development부분의 주석을 해제해 준다.

  networks: {
     ...
    // options below to some value.
    //
    development: {
     host: "127.0.0.1",     // Localhost (default: none)
     port: 8545,            // Standard Ethereum port (default: none)
     network_id: "*",       // Any network (default: none)
    },
    // Another network with more advanced options...
    ...
  • 이제 Truffle마이그레이션 명령으로 배포를 한다.
$ truffle migration

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.



Starting migrations...
======================
> Network name:    'development'
> Network id:      1645242745370
> Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------
   ⠋ Blocks: 0            Seconds: 0   > transaction hash:    0x7b9273e34dfc15ead19af00610bacd7491c5e9a538837a8022c1bfb0614a8b5c
   > Blocks: 0            Seconds: 0
   > contract address:    0xa2c98A4097BBFa1e5f4f467685687269bf7F0019
   > block number:        1
   > block timestamp:     1645242980
   > account:             0x3223E6492CA619a3aF219d36aA5ecAaCa914D1Eb
   > balance:             99.99502316
   > gas used:            248842 (0x3cc0a)
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.00497684 ETH


   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:          0.00497684 ETH


2_deploy_lottery.js
===================

   Deploying 'Lottery'
   -------------------
   ⠋ Blocks: 0            Seconds: 0   > transaction hash:    0xa3b53e7fe9d76806caf5e730894d8698fe099743efac0f6394befc71fc6cd53c
   > Blocks: 0            Seconds: 0
   > contract address:    0x17E3e654fC8CE5911fb78C6C5403F99BB46c16D5
   > block number:        3
   > block timestamp:     1645242981
   > account:             0x3223E6492CA619a3aF219d36aA5ecAaCa914D1Eb
   > balance:             99.9911084
   > gas used:            153225 (0x25689)
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.0030645 ETH


   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:           0.0030645 ETH

Summary
=======
> Total deployments:   2
> Final cost:          0.00804134 ETH

컨트랙트내 배포 함수 실행

우리의 목표는 배포한 컨트랙트 내에 있는 getSomeValue()를 수행하는 것이다. 이를 truffle console에서 실행해 보도록 하겠다.

  • truffle console실행
> truffle console
truffle(development)> 
  • 배포된 Lottery관련 함수 확인 : Lottery.를 입력하고 탭 키를 친다.
truffle(development)> Lottery.
 ....
Lottery.db                           Lottery.decodeLogs                   Lottery.defaults
Lottery.deployed                     Lottery.deployedBinary               Lottery.deployedBytecode
Lottery.deployedGeneratedSources     Lottery.deployedSourceMap            Lottery.detectNetwork   ...
  • Lottery.deployed가 있는지 확인 하고 이 결과 인스턴스를 lt라는 변수로 복사
truffle(development)> Lottery.deployed().then(function(instance){lt = instance})

lt.owner()로 복사 여부 확인

truffle(development)> lt.owner()
'0x3223E6492CA619a3aF219d36aA5ecAaCa914D1Eb'
  • getSomeValue() 수행확인
truffle(development)> lt.getSomeValue()
BN { negative: 0, words: [ 5, <1 empty item> ], length: 1, red: null }

words: [ 5, <1 empty item> ]를 통해 성공적으로 getSomeValue()의 리턴값인 5가 읽혔음을 알 수 있다.

  1. 이 내용은 인프런 강의인 Ethereum 실전! 초보자를 위한 Lottery Dapp개발 을 참고로 하였으며 해당 소스의 일부는 2022년 현재 truffle버전에서 돌아가지 않아 수정하였다.