[BEB] Section4 : ERC-20 ๊ฐœ๋ฐœ/ ๐Ÿ‘‰Solidity ๋‹ค์–‘ํ•œ ๊ฐœ๋ฐœ๋„๊ตฌ / ๐Ÿ‘‰ํด๋ ˆ์ดํŠผ KIP-7 (2)

jsg_koยท2022๋…„ 1์›” 24์ผ
0
post-custom-banner

Ganache

์ด๋”๋ฆฌ์›€ ๋…ธ๋“œ๋Š” Geth๋‚˜ Parity๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ์ด๋”๋ฆฌ์›€ ๋ฉ”์ธ(๋˜๋Š” ํ…Œ์ŠคํŠธ) ๋„คํŠธ์›Œํฌ์— ์ ‘์†ํ•˜์—ฌ ๋ธ”๋ก์„ ๋ชจ๋‘ ๋™๊ธฐํ™”์‹œ์ผœ์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ธ”๋ก์„ ๋™๊ธฐํ™” ์‹œํ‚ค๋Š”๋ฐ๋งŒ ํ•ด๋„ 2-3์ผ ์ •๋„ ์†Œ์š”๋˜๋ฉฐ, ํŠธ๋žœ์žญ์…˜์„ ๋ณด๋‚ด๋„ ๋ธ”๋ก์„ ์ฑ„๊ตดํ•˜๊ธฐ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋Š” ๋“ฑ, ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ๊ฐœ๋ฐœ ํ•  ๋•Œ ๋ถˆํŽธํ•œ ์ ์ด ๋งŽ๋‹ค.

๊ทธ๋ž˜์„œ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ๊ฐœ๋ฐœ ํ•  ๋•Œ๋Š” ๊ฐ€๋‚˜์Šˆ(Ganache)์™€ ๊ฐ™์€ ๊ฐ€์ƒ ํ˜น์€ ํ”„๋ผ์ด๋น— ๋„คํŠธ์›Œํฌ ์ƒ์—์„œ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ๊ตฌ๋™ํ•ด๋ณด๊ณ , ํ…Œ์ŠคํŠธ๋„ท์„ ๊ฑฐ์ณ ๋ฉ”์ธ๋„ท์— ์˜ฌ๋ฆฐ๋‹ค.

๐Ÿ”ฅ๊ฐœ๋ฐœ ๋ฐ ๋ฐฐํฌ ๊ณผ์ •

๊ฐœ๋ฐœ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

TestRPC -> TestNet -> MainNet
  • TestRPC : ๊ฐ€๋‚˜์Šˆ๋ฅผ ์‚ฌ์šฉํ•ด ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ ๊ฐœ๋ฐœ ์ง„ํ–‰
  • TestNet : ๊ฐœ๋ฐœ ์™„๋ฃŒ ํ›„ MainNet๊ณผ ๋™์ผํ•œ ํ™˜๊ฒฝ์—์„œ ํ…Œ์ŠคํŠธ
  • MainNet : ์‹ค์ œ ์„œ๋น„์Šค์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐฐํฌ

๐Ÿ”ฅGanache ์„ค์น˜ ๋ฐ ์‚ฌ์šฉ

๊ฐ€๋‚˜์Šˆ(Ganache)๋Š” ๊ฐ€์ƒ์˜ ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ๋ฅผ ์ƒ์„ฑํ•ด์„œ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ์ด๋‹ค.
๊ฐ€๋‚˜์Šˆ ๋“ฑ์„ ์ด์šฉํ•ด ๋งŒ๋“  ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ TestRPC๋ผ๊ณ  ํ•œ๋‹ค.

๊ฐ€๋‚˜์Šˆ ๋‹ค์šด๋กœ๋“œ

๋‹ค์šด๋กœ๋“œ ํ›„ ๊ฐ€๋‚˜์น˜ ์‹คํ–‰ ๋ช…๋ น์–ด ./ganache-2.5.4-linux-x86_64.AppImage

  • Ganache๋ฅผ Quickstart๋กœ ์‹คํ–‰์„ ํ•˜๋ฉด ๋‹ค์Œ ํ™”๋ฉด์ด ๋‚˜์˜จ๋‹ค.

    ํ™”๋ฉด์— ๋Œ€ํ•ด์„œ ๊ฐ„๋žตํžˆ ์„ค๋ช…ํ•˜๋ฉด

    • ํ˜„์žฌ ๊ฐ€์ƒ์˜ ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ๊ฐ€ ๋กœ์ปฌ์— ์šด์˜๋˜๊ณ  ์žˆ๋‹ค.

    • ํ•ด๋‹น ๋„คํŠธ์›Œํฌ์— ์ ‘์†ํ•˜๋ ค๋ฉด http://127.0.0.1:7545 ๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋‹ค.

    • 10๊ฐœ์˜ ๊ฐ€์ƒ ๊ณ„์ •์—๋Š” ๊ฐ๊ฐ 100 ์ด๋”์˜ ์ž”์•ก์ด ์ถฉ์ „๋˜์–ด ์žˆ๋‹ค.

      Ganache์—์„œ mining์ด ํ™œ์„ฑํ™”๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋กœ contract๋ฅผ ๋ฐฐํฌํ•˜๊ฑฐ๋‚˜ transaction์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

      ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒ๋‹จ์— 4๊ฐœ์˜ ํƒญ์€ ๊ฐ๊ฐ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

    • Accounts: account๋“ค์˜ ์ฃผ์†Œ, ์ž”๊ณ , ํŠธ๋žœ์žญ์…˜ ์ˆ˜

    • Blocks: block ๋ฒˆํ˜ธ, ์ƒ์„ฑ์‹œ์ , ์‚ฌ์šฉ๋œ ๊ฐ€์Šค, ํฌํ•จ๋œ ํŠธ๋žœ์žญ์…˜

    • Transactions: ์ „์ฒด ํŠธ๋žœ์žญ์…˜

    • Contracts : ํŠธ๋Ÿฌํ”Œ(Truffle) ํ”„๋กœ์ ํŠธ์— ํฌํ•จ๋œ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ

    • Events : ์ด๋ฒคํŠธ ๋ฆฌ์ŠคํŠธ

    • Logs: EthereumJS VM์˜ ๋กœ๊ทธ

Ganache-cli

GUI๊ฐ€ ํ•„์š”์—†๋‹ค๋ฉด ganache-cli์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
Truffle์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•  ๊ฒฝ์šฐ, truffle develop๋ช…๋ น์œผ๋กœ ganache-cli ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
Remix๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•  ๊ฒฝ์šฐ, MetaMask์—์„œ ๋กœ์ปฌ ๋„คํŠธ์›Œํฌ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๐Ÿ”ฅGanache์™€ Remix ์—ฐ๋™

์ด ๋ฐฉ๋ฒ•์€ ๊ฐœ๋ฐœ ๋ฐ ๋ฐฐํฌ๊ณผ์ •์—์„œ TestNet์— ํ•ด๋‹นํ•˜๋Š” ๊ณผ์ •์ด๋‹ค.
Remix๋ฅผ ์ด์šฉํ•˜์—ฌ TestRPC์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž.

Metamask์™€ Ganache ์—ฐ๋™

  1. Metamask์—์„œ ๋„คํŠธ์›Œํฌ๋ฅผ ์„ ํƒํ•˜๋Š” ํ•ญ๋ชฉ ์ค‘, '๋„คํŠธ์›Œํฌ ์ถ”๊ฐ€' ํ•ญ๋ชฉ์„ ์„ ํƒํ•œ๋‹ค.
  2. ๋„คํŠธ์›Œํฌ ์ถ”๊ฐ€ ํ™”๋ฉด์—์„œ ๋„คํŠธ์›Œํฌ ์ด๋ฆ„, ์ƒˆ RPC URL, ์ฒด์ธ ID๋ฅผ ๊ฐ๊ฐ ์ž…๋ ฅํ•ด์ค€๋‹ค.
    • ๋„คํŠธ์›Œํฌ ์ด๋ฆ„ : Ganache Network
    • ์ƒˆ RPC URL : http://127.0.0.1:7545
    • ์ฒด์ธ ID : 1337
  3. ์ƒˆ ๋„คํŠธ์›Œํฌ์— ์ ‘์†ํ•˜์—ฌ ์ž์‹ ์˜ ๊ณ„์ •์ด ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด Ganache ๊ณ„์ •์„ Metamask๋กœ ๊ฐ€์ ธ์™€์•ผํ•œ๋‹ค. Ganache์—์„œ Address ์˜† ์—ด์‡  ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ Private Key๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ Metamask์— ๊ณ„์ •์„ importํ•œ๋‹ค.

Ganache Network์— ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ๋ฐฐํฌ

  1. Metamask ๊ณ„์ •์„ ์ด์šฉํ•˜์—ฌ Remix ๊ณ„์ •๊ณผ ์—ฐ๋™ํ•œ๋‹ค. ERC-20 ํ† ํฐ ์ฝ”๋“œ๋ฅผ ์ค€๋น„ํ•œ๋‹ค.

  2. Ganache ๋„คํŠธ์›Œํฌ์— ERC-20 ํ† ํฐ์„ ๋ฐฐํฌํ•œ๋‹ค.

  3. Deployํ›„ Ganache๋ฅผ ๋ณด๋ฉด Current Block์ด 0์ด์˜€์ง€๋งŒ ํ•˜๋‚˜์˜ ๋ธ”๋ก์ด ์ƒ์„ฑ๋˜์—ˆ๋‹ค.

    Deploy์™€ ๋™์‹œ์— transaction์„ Ganache ๊ฐ€์ƒ ๋„คํŠธ์›Œํฌ์— ์ „์†กํ–ˆ๊ณ , ์ฑ„๊ตด์ด ์ผ์–ด๋‚˜์„œ ๋ธ”๋ก์ด 1๊ฐœ ์ƒ์„ฑ๋œ ๊ฒƒ์ด๋‹ค.

  4. Ropsten TestNet์—์„œ ์‚ฌ์šฉํ–ˆ๋˜๊ฒƒ ์ฒ˜๋Ÿผ ๋„คํŠธ์›Œํฌ์—์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.


  5. Transaction์„ ๋ˆŒ๋Ÿฌ์„œ ๋“ค์–ด๊ฐ€๋ฉด ๋ฐฉ๊ธˆ Deploy๋ฅผ ํ•˜๋ฉด์„œ ๋ฐœ์ƒ์‹œํ‚จ transaction์ด ๋“ค์–ด ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๊ฐ€ Ganche ๋„คํŠธ์›Œํฌ์— ๋ฐฐํฌ๋œ ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.


Ganache Network์—์„œ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ์‚ฌ์šฉ

  1. Metamask์—์„œ Ganache์— ๋ฐฐํฌํ•œ ํ† ํฐ ์ฃผ์†Œ๋ฅผ ์ด์šฉํ•ด ํ† ํฐ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

  2. ์ถ”๊ฐ€๋œ ํ† ํฐ์„ ๋‹ค๋ฅธ ๊ณ„์ •์œผ๋กœ ์ „์†กํ•ด๋ณธ๋‹ค.

  3. Ganache ๋„คํŠธ์›Œํฌ๋Š” ๋กœ์ปฌ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ์œผ๋กœ, ๋‹ค๋ฅธ ๋„คํŠธ์›Œํฌ์— ์žˆ๋Š” ๊ณ„์ •์œผ๋กœ ์ „์†ก์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
    Metamask์—์„œ ์ƒˆ๋กœ์šด ๊ณ„์ •์„ ๋งŒ๋“ค์–ด ์ „์†กํ•ด๋ณด์ž.

  4. ๋‹ค๋ฅธ ๊ณ„์ •์—์„œ ํ† ํฐ์„ ๋ฐ›์€๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  5. Ganache๋ฅผ ํ™•์ธํ•˜๋ฉด ๋ธ”๋ก์ด ํ•˜๋‚˜ ๋” ์ฑ„๊ตด์ด ๋˜์–ด ํŠธ๋žœ์žญ์…˜์ด ์ƒ๊ธด๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  6. ํ† ํฐ์˜ ๊ฐœ์ˆ˜๋ฅผ remix์—์„œ balanceOf ํ•จ์ˆ˜๋กœ ํ™•์ธํ•ด๋ณด์ž.

    ์ƒํƒœ ๋ณ€์ˆ˜๊ฐ€ ๋ณ€ํ•˜๋Š” "์“ฐ๊ธฐ" ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•  ๋•Œ์—๋งŒ ์ฑ„๊ตด์ด ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ๊ธฐ ์ „์šฉ ํ•จ์ˆ˜์—์„œ๋Š” ์ฑ„๊ตด์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

Truffle

truffle ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ(solidity) ๊ฐœ๋ฐœ์‹œ ๊ฐœ๋ฐœ, ๋ฐฐํฌ ๋ฐ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ์ œ๊ณต ํ•œ๋‹ค.
์ด ํ”„๋ ˆ์ž„์›Œํฌ๋Š” node.js์—์„œ ๋™์ž‘์„ ํ•˜๋ฉฐ npm ์œผ๋กœ ์„ค์น˜๋ฅผ ํ• ์ˆ˜ ์žˆ๋‹ค.

์š”๊ตฌ์‚ฌํ•ญ

  • NodeJS 5.0 ์ด์ƒ
  • ์œˆ๋„์šฐ, ๋ฆฌ๋ˆ…์Šค, Mac OS X
  • JSON RPC API ๋ฅผ ์ง€์›ํ•˜๋Š” ์ด๋”๋ฆฌ์›€ ํด๋ผ์ด์–ธํŠธ
npm install -g truffle

์„ค์น˜ ํ›„ truffle์„ ์‹คํ–‰ํ•˜์‹œ๋ฉด ๋ช…๋ น์–ด๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Truffle ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.
https://trufflesuite.com/docs/truffle/overview

๐Ÿ”ฅTruffle ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

  1. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด Truffle Sample Project๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

    mkdir sample
    cd sample
    truffle init //sample ํด๋”์—์„œ truffle init์„ ํ†ตํ•ด ํŠธ๋Ÿฌํ”Œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
  2. ์ •์ƒ์ ์œผ๋กœ ์ˆ˜ํ–‰์ด ๋˜๋ฉด ๋‹ค์Œ์˜ ํด๋” ๊ตฌ์กฐ๋กœ ์ƒ์„ฑ์ด ๋œ๋‹ค.

    • contracts: solidity๋กœ ๊ฐœ๋ฐœ๋œ ์Šค๋งˆํŠผ ์ปจํŠธ๋ž™ํŠธ ์†Œ์Šค ํŒŒ์ผ ํด๋”
    • contracts/Migrations.sol: ๋ฐฐํฌ๋ฅผ ๋„์™€์ฃผ๋Š” solidity ํŒŒ์ผ(์‚ญ์ œ ํ•˜์ง€ ๋งˆ์„ธ์š”!) ํ™•์ธํ•„์š”!
    • migrations: ๋ฐฐํฌ๋ฅผ์œ„ํ•œ ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ ํด๋”
    • migrations/1_initial_migration.js: Migrations.sol ์„ ๋ฐฐํฌํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ
    • test: ๊ฐœ๋ฐœ๋œ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ ์œ„ํ•œ ํด๋”
    • truffle-config.js: truffle ์„ค์ • ํŒŒ์ผ Migrations.sol ํŒŒ์ผ์„ ์‚ญ์ œํ•˜๋ฉด ๋ฐฐํฌ์‹œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋ฐฐํฌ์‹œ ๋‚ด๋ถ€์ ์œผ๋กœ ์ด ์ปจํŠธ๋ž™ํŠธ๋ฅผ ์‚ฌ์šฉํ•จ.

๐Ÿ”ฅTruffle Develop

TRUFFLE DEVELOP์€ truffle์—์„œ Ganache์™€ ๊ฐ™์€ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ์ด๋”๋ฆฌ์›€ ํด๋ผ์ด์–ธํŠธ์ด๋‹ค.

์ด๋”๋ฆฌ์›€ ํด๋ผ์ด์–ธํŠธ ์‹คํ–‰

truffle develop ์œ„ ๋ช…๋ น์–ด๋ฅผ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธํด๋”(sample ํด๋”)์—์„œ ์‹คํ–‰ํ•˜๋ฉด 10๊ฐœ์˜ Accounts์™€ Private Keys ๊ฐ€ ๋ฆฌ์ŠคํŠธ์—… ๋˜๋ฉด์„œ truffle(develop)> ํ”„๋กฌํ”„ํŠธ๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋œ๋‹ค. ๋˜ํ•œ JSON-RPC์šฉ(http://127.0.0.1:9545/) ์„œ๋น„์Šค๊ฐ€ ์ œ๊ณต๋œ๋‹ค. truffle console๋กœ ์ž…์žฅํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ์ฝ˜์†”์„ ์ข…๋ฃŒํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” .exit ์ž…๋ ฅํ•˜๋ฉด ์ฝ˜์†”์ด ์ข…๋ฃŒ๋œ๋‹ค.


์ด์ „์— ๋ฐฐ์› ๋˜ Ganache์™€ ๊ฐ™์€ ์—ญํ• ์„ ํ•˜๋Š” ์ด๋”๋ฆฌ์›€ ํด๋ผ์ด์–ธํŠธ์ด๋‹ค.

Ganache์—์„œ ๋ฐฐ์› ๋˜ ๋ฐฉ๋ฒ•๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ MetaMask์— ๊ณ„์ •์„ ์—ฐ๋™ํ•˜์—ฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.


์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ์—๋Š” ๋„คํŠธ์›Œํฌ ID์™€ ์ฒด์ธ ID์˜ ๋‘ ๊ฐ€์ง€ ์‹๋ณ„์ž๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๋„คํŠธ์›Œํฌ๋ฅผ ์ถ”๊ฐ€ํ• ๋•Œ, Truffle ๋„คํŠธ์›Œํฌ ์—ญ์‹œ ์ฒด์ธID๋ฅผ ๊ธฐ์ž…ํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ฒด์ธ ID์™€ ๋„คํŠธ์›Œํฌ ID์˜ ์ฐจ์ด์ ๊ณผ ์–ด๋””์— ์‚ฌ์šฉํ•˜๋Š”์ง€ ์ •ํ™•์ด ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์› ๋‹ค. ์ผ๋‹จ ์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์— ๊ฒ€์ƒ‰ํ•œ ๊ฒฐ๊ณผ ์ด๋Š” Ganache ์ธก์— ์žˆ๊ณ , Truffle ์ธก์—์„œ๋Š” Truffle ๊ตฌ์„ฑ ํŒŒ์ผ(truffle.js ๋˜๋Š” truffle-config.js)์„ ํ†ตํ•ด ํŠน์ • ๋„คํŠธ์›Œํฌ ID๋ฅผ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์‹ค์ œ๋กœ ์ฒด์ธID๋Š” 1337๋กœ Ganache์™€ ๊ฐ™์•˜๊ณ , ์ด ์ ์„ ๋ฏธ๋ฃจ์–ด ๋ณด์•„ ์ผ๋‹จ์€ Truffle ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋ณ„๋„์˜ ํ…Œ์ŠคํŠธ๋„ท์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ Ganache ํ…Œ์ŠคํŠธ ๋„ท์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋…ธ๋“œ ๊ฐ„์˜ P2P ํ†ต์‹ ์€ย ๋„คํŠธ์›Œํฌ IDย ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ˜๋ฉด ํŠธ๋žœ์žญ์…˜ ์„œ๋ช… ํ”„๋กœ์„ธ์Šค๋Š”ย ์ฒด์ธ IDย ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
EIP-155ย ๋Š” ํŠธ๋žœ์žญ์…˜ ์žฌ์ƒ ๊ณต๊ฒฉ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ํŠธ๋žœ์žญ์…˜ ์„œ๋ช… ํ”„๋กœ์„ธ์Šค์˜ ์ผ๋ถ€๋กœ ์ฒด์ธ ID๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋„์ž…๋˜์—ˆ๋‹ค.
https://besu.hyperledger.org/en/stable/Concepts/NetworkID-And-ChainID/
https://ethereum.stackexchange.com/questions/76581/what-is-the-networkid-and-chain-id-of-truffle-cli

์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ์ปดํŒŒ์ผ

truffle(develop)> compile

์œ„ ๋ช…๋ น์–ด ์‹คํ–‰์‹œ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ํด๋”์— /build ํด๋”๊ฐ€ ์ƒ์„ฑ์ด ๋˜๋ฉฐ contracts ํด๋” ์•„๋ž˜์— ์žˆ๋Š” solidity ํŒŒ์ผ์ด json ํ˜•ํƒœ๋กœ ๋ณ€๊ฒฝ๋˜์–ด ์ƒ์„ฑ์ด ๋œ๋‹ค.

์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ๋ฐฐํฌ

truffle(develop)> migrate

์œ„ ๋ช…๋ น์–ด ์‹คํ–‰์‹œ /build ํด๋”์— ์ƒ์„ฑ๋œ ํŒŒ์ผ์„ ์„œ๋ฒ„์— ๋ฐฐํฌ๊ฐ€ ๋œ๋‹ค.

์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ํ…Œ์ŠคํŠธ

truffle(develop)> test

์œ„ ๋ช…๋ น์–ด ์‹คํ–‰์‹œ /test ํด๋”์— ์žˆ๋Š” .js , .sol ํŒŒ์ผ์„ ์‹คํ–‰ํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

Solidity ํŒŒ์ผ๋กœ ํ…Œ์ŠคํŠธ ํŒŒ์ผ์„ ์ƒ์„ฑ์‹œ์— ํŒŒ์ผ๋ช…์€ contract ๋ช…๊ณผ ์ผ์น˜ ํ•˜๊ฒŒ ํ•˜๋ฉฐ, contract name์€ Test~ ๋กœ ์‹œ์ž‘ํ•˜๊ณ , ํ•จ์ˆ˜๋ช…๋„ test~ ๋กœ ์‹œ์ž‘ ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

๐Ÿ”ฅ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ํ†ตํ•œ ์‹ค์Šต

๊ฐ„๋‹จํ•œ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ์ƒ์„ฑํ•ด๋ณด์ž.

1. ์ƒ˜ํ”Œ ์ฝ”๋“œ ์ž‘์„ฑ

contracts/Sample.sol ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์—ฌ ํ•ด๋‹น ํŒŒ์ผ์— ๊ฐ„๋‹จํ•œ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ๋‚ด์šฉ์„ ์ €์žฅ ํ•œ๋‹ค.

์ฝ”๋“œ ๋งจ์œ„์— ๋ผ์ด์„ผ์Šค ์‹๋ณ„์ž ์‚ฌ์šฉํ•ด์•ผํ•จ // SPDX-License-Identifier: MIT

2. ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ

migrations/2_deploy_sample.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

์ปจํŠธ๋ž™ํŠธ๋ฅผ ํ˜ธ์ถœํ• ๋•Œ๋Š” ํŒŒ์ผ๋ช…์ด ์•„๋‹Œ ์ปจํŠธ๋ž™ํŠธ๋ช…์œผ๋กœ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
๋ฐฐํฌํŒŒ์ผ์„ ํ™•์ธํ•˜๋ฉด ํŒŒ์ผ๋ช… ์•ž์— ์ˆซ์ž๊ฐ€ ๋ถ™์–ด ์žˆ๋‹ค.
migrations ํด๋” ์•„๋ž˜์— ํฌํ•จ๋œ ๋ชจ๋“  ํŒŒ์ผ์„ ์‹คํ–‰ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐํฌ์‹œ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ฃผ๊ธฐ ์œ„ํ•ด ์•ž์— ์ˆซ์ž๋ฅผ ๋ถ™์—ฌ ์ค€๋‹ค.

3. ํ…Œ์ŠคํŠธ ์ปจํŠธ๋ž™ํŠธ ์ž‘์„ฑ

test/TestSimpleStorage.sol ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

์œ„ ์ฝ”๋“œ๋ฅผ ์ค€๋น„ํ•˜๋ฉด ํ…Œ์ŠคํŠธ ๊ณผ์ •์ด ๋ชจ๋‘ ์ค€๋น„๊ฐ€ ๋๋‹ค.
์ด์ œ ์ปดํŒŒ์ผ ํ›„ Ethereum Client(Truffle Develop)์— ๋ฐฐํฌํ•˜๊ณ  ํ…Œ์ŠคํŠธ๊นŒ์ง€ ๊ณผ์ •์„ ์ง„ํ–‰ํ•œ๋‹ค.

4. ์ปดํŒŒ์ผ

truffle(develop)> compile

5. ๋ฐฐํฌ

truffle(develop)> migrate

6. ํ…Œ์ŠคํŠธ

truffle(develop)> test
Using network 'develop'.

Compiling ./contracts/Storage.sol...
Compiling ./test/TestSimpleStorage.sol...
Compiling truffle/Assert.sol...
Compiling truffle/DeployedAddresses.sol...

  TestSimpleStorage
    โœ“ testSimpleStorage (57ms)

  1 passing (589ms)

ํ…Œ์ŠคํŠธ ๊ณผ์ •์—์„œ ๋ช‡ ๊ฐ€์ง€ ์—๋Ÿฌ๊ฐ€ ์žˆ์—ˆ๋‹ค. ๊ฑฐ์˜ 2์‹œ๊ฐ„๋™์•ˆ ์‚ฝ์งˆํ–ˆ๋‹ค.. ์ง„์งœ....

๊ฒฐ๊ตญ ํ…Œ์ŠคํŠธํŒŒ์ผ์˜ ์•„๋ž˜์˜ ๋ชจ๋“ˆ๋“ค์„ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ•˜๋Š” ์—๋Ÿฌ๋Š” ํŠธ๋Ÿฌํ”Œ ๋ฒ„์ „ v5.4.30 ์œผ๋กœ ๋ณ€๊ฒฝ ํ•˜๋Š” ๊ฒƒ ์œผ๋กœ ํ•ด๊ฒฐํ–ˆ๋‹ค.

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Storage.sol";

์œ„ ํ™”๋ฉด ํ™•์ธ์„ ํ†ตํ•ด truffle develop์— ๋ฐฐํฌ, ํ…Œ์ŠคํŠธ๊นŒ์ง€ ์™„๋ฃŒํ–ˆ๋‹ค.

๐Ÿ”ฅTruffle๊ณผ Ganache ์—ฐ๋™

Ganache ์—ฐ๋™์„ ์œ„ํ•ด ๋„คํŠธ์›Œํฌ ์„ค์ •์„ ํ•ด์•ผํ•œ๋‹ค.

  1. truffle-config.js ํŒŒ์ผ์„ ๊ฐ„๋‹จํžˆ ์ˆ˜์ •ํ•œ๋‹ค.

    development: {
        host: "127.0.0.1",
        port: 7545,
        network_id: "5777",
      },
  2. ์ˆ˜์ • ํ›„ truffle networks ํ™•์ธ์„ ์ง„ํ–‰ํ•œ๋‹ค.

    development ๋„คํŠธ์›Œํฌ๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ๋“ฑ๋ก๋œ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  3. ์ด์ „์— ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ–ˆ๋˜ ํŒŒ์ผ์„ ๊ทธ๋Œ€๋กœ Ganache ๋„คํŠธ์›Œํฌ์— ์—…๋ฐ์ดํŠธ ํ•ด๋ณด์ž.

    Ganache ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋ผ์žˆ๋Š”(7545ํฌํŠธ ๋„คํŠธ์›Œํฌ๊ฐ€ ์—ด๋ ค์žˆ๋Š”) ์ƒํƒœ์—์„œ truffle compile truffle migrate ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด Ganache ๋„คํŠธ์›Œํฌ์— ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

    ํŠธ๋žœ์žญ์…˜์ด ๋ฐฐํฌ๋˜๊ณ , ๋ธ”๋ก๋„ ์ƒ์„ฑ๋œ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

    ํŠธ๋žœ์žญ์…˜ ํ•œ๊ฐœ๋‹น ๋ธ”๋ก 1๊ฐœ ์ƒ์„ฑ ์ด4๊ฐœ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ๋Š”๋ฐ ์ปจํŠธ๋žœํŠธ ํ˜ธ์ถœ ํŠธ๋žœ์žญ์…˜์€ ์–ด๋–ป๊ฒŒ ํ˜ธ์ถœ๋๋Š”์ง€ ์•„์ง ์ž˜ ์ดํ•ด๊ฐ€ ๊ฐ€์ง€ ์•Š๋Š”๋‹ค.

OpenZeppelin

์˜คํ”ˆ์ œํ”Œ๋ฆฐ์€ ์†”๋ฆฌ๋””ํ‹ฐ ๊ธฐ๋ฐ˜์˜ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ธ ์˜คํ”ˆ์ œํ”Œ๋ฆฐ(OpenZeppelin)๊ณผ, ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์šด์˜ํ•˜๋Š” ํ”Œ๋žซํผ์ธ ์ œํ”Œ๋ฆฐOS๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค.

๐Ÿ”ฅTruffle์„ ์ด์šฉํ•œ openzeppelin-solidity Library ํ™œ์šฉ

  1. ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์ƒˆ๋กœ์šด ํด๋”๋ฅผ ๋งŒ๋“ ๋‹ค.

    mkdir openZeppelinSample
    cd openZeppelinSample
    truffle init
  2. openZeppelinSample ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ  truffle init์„ ํ†ตํ•ด ํŠธ๋Ÿฌํ”Œ ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™”๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

  3. ์†”๋ฆฌ๋””ํ‹ฐ ์‚ฌ์šฉ์„ ์œ„ํ•œ openzeppelin solidity ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

    npm install -E openzeppelin-solidity

    gyp ERR! stack Error: make failed with exit code: 2 ์—๋Ÿฌ
    git init, npm init์œผ๋กœ ํ•ด๊ฒฐ

    node_modules ์—์„œ openzeppelin-solidity ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


4. ๋งŒ์•ฝ ์†”๋ฆฌ๋””ํ‹ฐ ๋ฒ„์ „์ด openzepellin ๋ฒ„์ „๊ณผ ๋‹ค๋ฅด๋‹ค๋ฉด truffle-config.js๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค.

compilers : {
    solc : {
            version : "0.8.10",
    }
}

OpenZeppelin ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ™œ์šฉ ERC-20 ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ์ž‘์„ฑ

  1. ZeppelinTestToken.sol ํŒŒ์ผ์„ ์ž‘์„ฑํ•œ๋‹ค.

    // SPDX-License-Identifier: GPL-3.0
    pragma solidity 0.8.10;
    
    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
    
    contract ZeppelinTestToken is ERC20 {
        constructor() ERC20("ZeppelinTestToken", "ZTT") {
              _mint(msg.sender, 100000000e18);
        }
    
    }
  2. migrations ํด๋” ์•ˆ์— 2_deploy_ZeppelinTestToken.js๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

    var ZeppelinTestToken = artifacts.require("ZeppelinTestToken");
    
    module.exports = function(deployer) {
        deployer.deploy(ZeppelinTestToken);
    };
  3. ๋ฐฐํฌ๋ฅผ ํ•˜๊ธฐ์ „ ์‚ฌ์šฉํ•  openzeppelin/contract ๊ฒฝ๋กœ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.


ZeppelinTestToken.sol ํŒŒ์ผ์˜ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด import๋ฅผ ํ†ตํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์กด์žฌํ•˜๋Š” ERC20.sol ํŒŒ์ผ์„ ๊ฐ€์ ธ์™€์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. ์ดํ›„ ๋ฐฐํฌ๋ฅผ ์ง„ํ–‰ํ•˜์—ฌ Ganache์—์„œ ๋ธ”๋ก ์ƒ์„ฑ๊ณผ Metamask๋ฅผ ํ™œ์šฉํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹ค์‹œํ•œ๋‹ค.

    truffle migrate

    OpenZeppelin ERC-20 Library

    ํ…Œ์ŠคํŠธ๊ฒฐ๊ณผ Ganache ํ…Œ์ŠคํŠธ๋„ท์—์„œ ๋ฉ”ํƒ€๋งˆ์Šคํฌ์— ์ง€๊ฐ‘ ์ถ”๊ฐ€, ZTT ํ† ํฐ ์ถ”๊ฐ€, ํ† ํฐ ์ „์†ก ๋ชจ๋‘ ์ž˜ ์ž‘๋™ํ•œ๋‹ค.

๐Ÿ”ฅRemix์—์„œ OpenZeppelin Library ์‚ฌ์šฉํ•˜๊ธฐ

Remix์—์„œ๋Š” ์ž๋™์œผ๋กœ npm ํŒจํ‚ค์ง€๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

  • ZeppelinTestToken.sol ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์œ„์—์„œ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • .deps/npm ์•„๋ž˜๋กœ @openzeppelin์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ดํ›„ ์ด์ „๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ปดํŒŒ์ผ ํ›„ ํ…Œ์ŠคํŠธ๋„ท์— ๋ฐฐํฌํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ํ…Œ์ŠคํŠธ๊ฒฐ๊ณผ Ganache ํ…Œ์ŠคํŠธ๋„ท์—์„œ ๋ฉ”ํƒ€๋งˆ์Šคํฌ์— ์ง€๊ฐ‘ ์ถ”๊ฐ€, ZTT ํ† ํฐ ์ถ”๊ฐ€, ํ† ํฐ ์ „์†ก ๋ชจ๋‘ ์ž˜ ์ž‘๋™ํ•œ๋‹ค.

ํด๋ ˆ์ดํŠผ KIP-7

๐Ÿ”ฅ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๊ตฌ์„ฑ

ํด๋ ˆ์ดํŠผ์€ ์ด๋”๋ฆฌ์›€ ๊ธฐ๋ฐ˜ ํ”Œ๋žซํผ์œผ๋กœ, ์ด๋”๋ฆฌ์›€์˜ ์‹œ์Šคํ…œ๊ณผ ๋งŽ์ด ๋น„์Šทํ•˜๋‹ค.

Klaytn Wallet

์ด๋”๋ฆฌ์›€์— ์žˆ๋Š” MyEtherWallet๊ณผ ๊ฐ™์ด, ํด๋ ˆ์ดํŠผ์—๋„ Klaytn Wallet์ด๋ผ๋Š” ์›น ์ง€๊ฐ‘์ด ์žˆ๋‹ค.

Klaytn Wallet์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” Key ํŒŒ์ผ์„ ํ†ตํ•ด MyEthereWallet๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Kaikas Wallet

๋˜ํ•œ, ์ด๋”๋ฆฌ์›€์— ์žˆ๋Š” MetaMask์™€ ๊ฐ™์ด, ํด๋ ˆ์ดํŠผ์—๋„ Kaikas Wallet์ด ์žˆ๋‹ค.

Kaikas Wallet์˜ ๊ธฐ๋ณธ ๊ตฌ์„ฑ์€ Metamask์™€ ๋น„์Šทํ•˜๋‹ค. UI/UX ์œ„์น˜๋งŒ ๋ณ€๊ฒฝ๋˜์—ˆ๊ณ  ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ˜•ํƒœ๋Š” ๋™์ผํ•˜๋‹ค.

Klaytn IDE

  • ์ด๋”๋ฆฌ์›€์˜ Remix๋Š” ํด๋ ˆ์ดํŠผ์—์„œ Klaytn IDE์ด๋‹ค.

    Klaytn IDE : https://ide.klaytn.com/
    Klaytn IDE๋Š” 2022๋…„ 1์›” 6์ผ์„ ๊ธฐ์ ์œผ๋กœ ํ˜„์žฌ Remix ๋ฒ„์ „๊ณผ ๋™์ผํ•˜๊ฒŒ ์—…๋ฐ์ดํŠธ๋˜์—ˆ๋‹ค.
    ๋ฉ”์ธ๋„ท๊ณผ ํ…Œ์ŠคํŠธ๋„ท์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์†”๋ฆฌ๋””ํ‹ฐ ๋ฒ„์ „์€ ํ…Œ์ŠคํŠธ๋„ท๊ณผ ๋ฉ”์ธ๋„ท์˜ ์ˆœ์„œ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ์˜ˆ์ •๋˜์–ด ์žˆ๋‹ค.

    ํด๋ ˆ์ดํŠผ์€ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ์–ธ์–ด๋กœ ์†”๋ฆฌ๋””ํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ํ˜„์žฌ ๋ฉ”์ธ๋„ท์— ์ ์šฉ๋œ ์†”๋ฆฌ๋””ํ‹ฐ ๋ฒ„์ „์€ 0.5.6 ๋ฒ„์ „์ด๋‹ค.
  • Account ์˜†์—์žˆ๋Š” + ๋ฒ„ํŠผ์„ ํ†ตํ•ด ๊ณ„์ •์„ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ๋‹ค. Private Key ๋˜๋Š” Key File์„ ํ†ตํ•ด Klaytn IDE ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Truffle

ํด๋ ˆ์ดํŠผ์˜ ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ๋˜ํ•œ Truffle๋กœ ์ปดํŒŒ์ผํ•˜๊ณ  ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋‹ค.

ํด๋ ˆ์ดํŠผ ํŠธ๋Ÿฌํ”Œ ์‚ฌ์šฉ๋ฒ•: https://ko.docs.klaytn.com/smart-contract/ide-and-tools/truffle

๋จผ์ € ํด๋ ˆ์ดํŠผ์—์„œ Truffle์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฐ€๋‚˜์Šˆ์™€ ๊ฐ™์€ ์—ญํ• ์„ ํ•˜๋Š” EN ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๋กœ์ปฌ EN ๋…ธ๋“œ ๋ฐฐํฌ ๋ฐฉ๋ฒ• : https://ko.docs.klaytn.com/getting-started/quick-start/deploy-a-smart-contract#deploying-a-smart-contract-using-truffle

์›๊ฒฉ EN ๋…ธ๋“œ๋กœ ๋ฐฐํฌ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” truffle-hdwallet-provider-klaytn ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

truffle-hdwallet-provider-klaytn ํ”„๋ ˆ์ž„์›Œํฌ : https://www.npmjs.com/package/truffle-hdwallet-provider-klaytn

๐Ÿ”ฅBaobab Network์— ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ๋ฐฐํฌํ•˜๊ธฐ

Klaytn IDE ์‚ฌ์šฉ

Klaytn IDE๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Baobab Network์— ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ๋ฅผ ๋ฐฐํฌํ•ด๋ณด์ž.

  1. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ Klaytn IDE์— ์ž…๋ ฅํ•œ๋‹ค.

    pragma solidity 0.5.6;
    
    contract Count {
        uint256 public count = 0;
    
        function setCount(uint256 _count) public {
          count = _count;
        }
    }
  2. KLAY๋ฅผ ๋ฐ›์€ ๊ณ„์ •์„ IDE์— Importํ•˜์—ฌ Baobab Network์— ๋ฐฐํฌ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค. Deploy์— ์„ฑ๊ณตํ•˜๋ฉด ํ„ฐ๋ฏธ๋„์— ๋กœ๊ทธ์™€ ํ•จ๊ป˜ ์ขŒ์ธก ํ•˜๋‹จ์— Deployed Contract๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์ปจํŠธ๋ž™ํŠธ ์ปดํŒŒ์ผ๋Ÿฌํ• ๋•Œ์— EVM VERSION ์ค‘ constantinople ๋กœ ์ง„ํ–‰ํ•˜์˜€๋‹ค.
    ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ–ˆ๋‹ค.
    Klaytn์€ Solidity๋กœ ์ž‘์„ฑ๋œ ๊ณ„์•ฝ์„ ์ง€์›ํ•˜๋ฉฐ EVM์˜ ์ฝ˜์Šคํƒ„ํ‹ฐ๋…ธํ”Œ ๋ฒ„์ „ ๊ณผ ํ˜ธํ™˜

    ํด๋ ˆ์ดํŠผ์šฉ ๋ธ”๋กํƒ์ƒ‰๊ธฐ (;์ด๋”์Šค์บ”๊ฐ™์€) ์—์„œ ๋ฐฐํฌํ•œ ํŠธ๋žœ์žญ์…˜์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

  3. SetCount ํ•จ์ˆ˜์™€ Public์œผ๋กœ ์„ ์–ธ๋œ Count ๋ณ€์ˆ˜๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. SetCount์— ์ˆซ์ž๋ฅผ ๋„ฃ์–ด ํŠธ๋žœ์žญ์…˜์„ ์‹คํ–‰์‹œ์ผœ๋ณด๊ณ , Count ๋ณ€์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์™€ ๊ฐ™์€ ์ˆซ์ž๋ฅผ ์ž˜ ๋ถˆ๋Ÿฌ์˜ค๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž.

๐Ÿ”ฅKIP-7 ๋ฐฐํฌ

KIP-7

ํด๋ ˆ์ดํŠผ์—์„œ๋Š” ์ด๋”๋ฆฌ์›€์— ์กด์žฌํ•˜๋Š” EIP์™€ ๋™์ผํ•œ KIP(Klaytn Improvement Proposals)๊ฐ€ ์กด์žฌํ•œ๋‹ค. ๊ทธ์ค‘ Fungible Token Standard์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ KIP-7์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

KIP-7์€ ERC-20์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ๋‚ด์šฉ์ด๋‹ค.

// KIP7 Interface
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function safeTransfer(address recipient, uint256 amount, bytes data) external;
function safeTransfer(address recipient, uint256 amount) external;
function safeTransferFrom(address sender, address recipient, uint256 amount, bytes data) external;
function safeTransferFrom(address sender, address recipient, uint256 amount) external;

์œ„์˜ ์ฝ”๋“œ๋Š” ๊ธฐ๋ณธ์ ์ธ KIP-7์˜ ์ธํ„ฐํŽ˜์ด์Šค ๋ชฉ๋ก์ด๋‹ค.

๋˜ํ•œ ์˜คํ”ˆ์ œํ”Œ๋ฆฐ์ฒ˜๋Ÿผ ํด๋ ˆ์ดํŠผ์—์„œ๋Š” ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ ๊ฐœ๋ฐœ์„ ์œ„ํ•œ ๊ณต์‹ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์œ„์˜ ๋งํฌ ๋ฌธ์„œ์—์„œ๋Š” KAS๋ผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ด์šฉํ•˜์—ฌ EN๋…ธ๋“œ์— truffle๋กœ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ๋‹ค. ์ด ๊นƒํ—ˆ๋ธŒ์—์„œ KIP-7์— ๋Œ€ํ•œ ์ฝ”๋“œ๋ฅผ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค. KIP-7.sol

KIP-7.sol ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ SimpleKlaytnToken๋ฅผ ๋งŒ๋“ค์–ด Baobab Network์—์„œ ํ† ํฐ์„ ์‚ฌ์šฉํ•ด๋ณด์ž

SimpleKlaytnToken

[SimpleKlaytnToken ์ปจํŠธ๋ž™ํŠธ ์ฝ”๋“œ]

pragma solidity 0.5.6;

contract IKIP {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function transferFrom(address spender, address recipient, uint256 amount) external returns (bool);
    
    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Transfer(address indexed spender, address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 oldAmount, uint256 amount);
}

contract SimpleKlaytnToken is IKIP {
    mapping (address => uint256) private _balances;
    mapping (address => mapping (address => uint256)) public _allowances;

    uint256 public _totalSupply;
    string public _name;
    string public _symbol;
    uint8 public _decimals;
    
    constructor(string memory getName, string memory getSymbol) public {
        _name = getName;
        _symbol = getSymbol;
        _decimals = 18;
        _totalSupply = 100000000e18;
        _balances[msg.sender] = _totalSupply;
    }
    
    function name() public view returns (string memory) {
        return _name;
    }
    
    function symbol() public view returns (string memory) {
        return _symbol;
    }
    
    function decimals() public view returns (uint8) {
        return _decimals;
    }
    
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }
    
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }
    
    function transfer(address recipient, uint amount) public returns (bool) {
        _transfer(msg.sender, recipient, amount);
        emit Transfer(msg.sender, recipient, amount);
        return true;
    }
    
    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowances[owner][spender];
    }
    
    function approve(address spender, uint amount) public returns (bool) {
        uint256 currentAllownace = _allowances[msg.sender][spender];
        require(currentAllownace >= amount, "ERC20: Transfer amount exceeds allowance");
        _approve(msg.sender, spender, currentAllownace, amount);
        return true;
    }
    
    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
        _transfer(sender, recipient, amount);
        emit Transfer(msg.sender, sender, recipient, amount);
        uint256 currentAllowance = _allowances[sender][msg.sender];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        _approve(sender, msg.sender, currentAllowance, currentAllowance - amount);
        return true;
    }
    
    function _transfer(address sender, address recipient, uint256 amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;
    }
    
    function _approve(address owner, address spender, uint256 currentAmount, uint256 amount) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");
        require(currentAmount == _allowances[owner][spender], "ERC20: invalid currentAmount");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, currentAmount, amount);
    }
}
  1. KIR-7 ์ฝ”๋“œ๋ฅผ Klaytn IDE์— ์ž…๋ ฅํ•˜๊ณ  ์ปดํŒŒ์ผ ํ•œ ๋‹ค์Œ Deploy์— name๊ณผ symbol์„ ์ž…๋ ฅ ํ›„ Deployํ•œ๋‹ค.

  2. ์ดํ›„์—๋Š” ์ด๋”๋ฆฌ์›€ remix๋กœ ํ…Œ์ŠคํŠธ๋„ท์„ ์ด์šฉํ•ด ํ† ํฐ์ƒ์„ฑํ›„ ๋ฉ”ํƒ€๋งˆ์Šคํฌ์— ํ† ํฐ์„ ์ถ”๊ฐ€ํ•œ ๊ฒƒ ๊ณผ ๋˜‘๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ•˜๋ฉด ๋œ๋‹ค.

  3. ๋ฐ”์˜ค๋ฐฅ ํ…Œ์ŠคํŠธ๋„ท์— ํ† ํฐ์ด ์ •์ƒ์ ์œผ๋กœ ์ƒ์„ฑ ๋˜์—ˆ๊ณ , Transfer Transaction์„ ๋ฐœ์ƒ์‹œ์ผœ ํ† ํฐ ์ „์†ก๋˜ํ•œ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

profile
๋””๋ฒ„๊น…์—์„œ ์žฌ๋ฏธ๋ฅผ ์ถ”๊ตฌํ•˜๋ฉด ์•ˆ๋˜๋Š” ๊ฑธ๊นŒ
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€