# Sample Contracts

## Truffle 개발 환경 설치

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

### 요구사항

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

### Truffle 설치

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

<pre><code><strong>$ npm install -g truffle
</strong></code></pre>

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
```

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

<pre><code><strong>$ tree
</strong>.
├── contracts
├── migrations
├── test
└── truffle-config.js

4 directories, 1 file
</code></pre>

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

```
$ truffle create contract KVStore
```

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

<pre><code><strong>// SPDX-License-Identifier: MIT
</strong>pragma solidity >=0.4.22 &#x3C;0.9.0;

contract KVStore {
  constructor() public {
  }
}
</code></pre>

## 스마트 컨트랙트 작성

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를 설정하였습니다.

<pre><code><strong>/**
</strong><strong> ...
</strong><strong> */
</strong><strong>require('dotenv').config();
</strong><strong>// const { MNEMONIC, PROJECT_ID } = process.env;
</strong><strong>const { PRIVATE_KEY } = process.env;
</strong>
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"
      }
    }
  },
</code></pre>

## 스마트 컨트랙트 컴파일

```
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
```
