Sample Contracts

이 장에서는 Truffle 개발 환경을 이용하여 스마트 컨트랙트를 작성하고 배포하는 방법을 설명합니다.

Truffle 개발 환경 설치

Truffle은 메타디움과 같이 EVM(Ethereum Virtual Machine) 을 사용하는 블록체인에서 스마트 컨트랙트를 개발하고 테스트할 수 있는 환경입니다.

요구사항

Truffle을 사용하기 위해서는 윈도우즈, 리눅스, 맥OS 환경에서 Node.js v14 - v18가 설치되어 있어야 합니다.

Truffle 설치

터미널에서 NPM을 사용하여 Truffle을 설치합니다.

$ npm install -g truffle

Truffle의 설치를 확인하기 위해서는 다음 명령을 수행하세요.

$ truffle version
Truffle v5.11.5 (core: 5.11.5)
Ganache v7.9.1
Solidity - 0.8.21 (solc-js)
Node v18.19.0
Web3.js v1.10.0

프로젝트 생성

새로운 Truffle 프로젝트를 위해 새 디렉터리를 생성합니다. 예제에서는 key/value storage를 구현하는 스마트 컨트랙트를 만들어보기로 합니다. 이를 위해 KVStore라는 디렉터리를 생성합니다.

$ mkdir KVStore
$ cd KVStore

Truffle 프로젝트를 초기화 합니다.

$ truffle init

Starting init...
================

> Copying project files to /Users/trident/Projects/DApp/KVstore/Temp

Init successful, sweet!

Try our scaffold commands to get started:
  $ truffle create contract YourContractName # scaffold a contract
  $ truffle create test YourTestName         # scaffold a test

http://trufflesuite.com/docs

다음과 같은 디랙터리와 파일이 생성되니다.

$ tree
.
├── contracts
├── migrations
├── test
└── truffle-config.js

4 directories, 1 file

다음 명령으로 KVStore 컨트랙트를 생성합니다.

$ truffle create contract KVStore

아래와 같이 KVStore.sol 파일이 생성됩니다.

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract KVStore {
  constructor() public {
  }
}

스마트 컨트랙트 작성

Key/Value를 저장하는 set 함수와 Key를 이용하여 저장된 값을 읽어오는 get 함수를 다음과 같이 작성합니다.

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract KVStore {
  mapping(string => string) store;

  function get(string memory key) public view returns(string memory) {
    return store[key];
  }

  function set(string memory key, string memory value) public {
    store[key] = value;
  }
}

설정

컴파일 및 배포를 위해서 truffle-config.js 파일을 수정합니다.

첫 번째로 지갑 설정이 필요합니다. 코드 상에 개인키를 노출하지 않기 위해 dotenv를 사용하고 PRIVATE_KEY는 .env에 다음과 같이 저장합니다. dotenv를 사용할 경우 npm i dotenv 명령을 사용하여 설치를 해주어야 컴파일 시 에러가 발생하지 않습니다.

PRIVATE_KEY=["YOUR_PRIVATE_KEY"]

두 번째로 네트워크 설정을 진행합니다. Metadium Testnet를 사용하기 위해서는 다음과 같이 네트워크 설정을 추가합니다.

metadium_testnet: {
  provider: ()=> new HDWalletProvider(PRIVATE_KEY, "https://api.metadium.com/dev"),
  network_id: 12,
  gasPrice: 80000000000
}

마지막으로 컴파일러 설정을 진행합니다. 예제에서는 0.8.21을 사용하였으며, optimizer를 설정하였습니다.

/**
 ...
 */
require('dotenv').config();
// const { MNEMONIC, PROJECT_ID } = process.env;
const { PRIVATE_KEY } = process.env;

const HDWalletProvider = require('@truffle/hdwallet-provider');

module.exports = {
  ...
  networks: {
    ...
    metadium_testnet: {
      provider: ()=> new HDWalletProvider(PRIVATE_KEY, "https://api.metadium.com/dev"),
      network_id: 12,
      gasPrice: 80000000000
    }
  },
  ...
  compilers: {
    solc: {
      version: "0.8.21",      // 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: true,
          runs: 200
        },
        evmVersion: "byzantium"
      }
    }
  },

스마트 컨트랙트 컴파일

truffle compile

Compiling your contracts...
===========================
> Compiling ./contracts/KVStore.sol
> Artifacts written to /Users/trident/Projects/DApp/KVstore/Temp/build/contracts
> Compiled successfully using:
   - solc: 0.8.21+commit.d9974bed.Emscripten.clang

스마트 컨트랙트 배포

스마트 컨트랙트를 배포하기 전 migrations 디렉토리에 1_deploy_contracts.js 스크립트 파일을 다음과 같이 작성한다.

ar KVStore = artifacts.require("KVStore");

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

truffle migrate 명령어로 컨트랙트를 배포한다.

truffle migrate --network metadium_testnet

Starting migrations...
======================
> Network name:    'metadium_testnet'
> Network id:      12
> Block gas limit: 105000000 (0x6422c40)


1_deploy_contracts.js
=====================

   Deploying 'KVStore'
   -------------------
   > transaction hash:    0x1039d819b825a80281d27ae737858579752192b642e0678902570c64791739b0
   > Blocks: 2            Seconds: 4
   > contract address:    0x4981bEF8190D4CC385e4b0DcE67Faf24347dbB87
   > block number:        50419826
   > block timestamp:     1707187839
   > account:             0xcf3C2104DF83d92C845d71Be6354266b222295aD
   > balance:             10.443230699997734106
   > gas used:            322126 (0x4ea4e)
   > gas price:           80 gwei
   > value sent:          0 ETH
   > total cost:          0.02577008 ETH

   > Saving artifacts
   -------------------------------------
   > Total cost:          0.02577008 ETH

Summary
=======
> Total deployments:   1
> Final cost:          0.02577008 ETH

Last updated