๐ฉ ํ๋ํ์ผ๋ก ์ค๋งํธ ์ปจํธ๋ํธ ํ ์คํธ ์๋ํํ๊ธฐ ๐

์๋ ํ์ธ์, ๋ธ๋ก์ฒด์ธ ๊ฐ๋ฐ์ ์ฌ๋ฌ๋ถ! ์ค๋์ ์ ๋ง ํฅ๋ฏธ์ง์งํ ์ฃผ์ ๋ก ์ฐพ์์์ด์. ๋ฐ๋ก 'ํ๋ํ์ ์ด์ฉํ ์ค๋งํธ ์ปจํธ๋ํธ ํ ์คํธ ์๋ํ'์ ๋ํด ๊น์ด ํํค์ณ๋ณผ ๊ฑฐ์์. ์ด ๊ธ์ ์ฝ๋ค ๋ณด๋ฉด ์ฌ๋ฌ๋ถ๋ ์ด๋์ ์ค๋งํธ ์ปจํธ๋ํธ ํ ์คํธ์ ๋ฌ์ธ์ด ๋ ์ ์์ ๊ฑฐ์์! ๐
๋จผ์ , ์ฐ๋ฆฌ๊ฐ ๋ค๋ฃฐ ๋ด์ฉ์ด ์ข ์ด๋ ค์ธ ์ ์๋ค๋ ๊ฑธ ์ธ์ ํด์ผ ํด์. ํ์ง๋ง ๊ฑฑ์ ๋ง์ธ์! ์ ๊ฐ ์ต๋ํ ์ฝ๊ณ ์ฌ๋ฏธ์๊ฒ ์ค๋ช ํด๋๋ฆด๊ฒ์. ๋ง์น ์น๊ตฌ์ ์นดํก์ผ๋ก ์๋ค ๋ ๋ ๊ฒ์ฒ๋ผ์. ใ ใ ใ
๊ทธ๋ผ ์ด์ ๋ถํฐ ํ๋ํ์ ์ธ๊ณ๋ก ๋น ์ ธ๋ณผ๊น์? ๐โโ๏ธ
๐ญ ํ๋ํ์ด ๋ญ๊ธธ๋? ๐ค
์, ์ฌ๋ฌ๋ถ! ํ๋ํ์ด๋ผ๊ณ ๋ค์ด๋ณด์ จ๋์? ์๋ง ๊ฑด์ค ํ์ฅ์์ ์ฐ๋ ๊ทธ ๋ ธ๋ ๋ชจ์๋ฅผ ๋ ์ฌ๋ฆฌ์ จ์ ์๋ ์๊ฒ ์ด์. ใ ใ ใ ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ ์ค๋ ์ด์ผ๊ธฐํ ํ๋ํ์ ๊ทธ๊ฒ ์๋์์!
ํ๋ํ(Hardhat)์ ์ด๋๋ฆฌ์ ๊ฐ๋ฐ์ ์ํ ๊ฐ๋ ฅํ ๊ฐ๋ฐ ํ๊ฒฝ์ด์์. ์ฝ๊ฒ ๋งํด์, ์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ๋ง๋ค๊ณ ํ ์คํธํ๊ณ ๋ฐฐํฌํ๋ ๋ฐ ๋์์ ์ฃผ๋ ๋ ๋ ํ ์น๊ตฌ๋ผ๊ณ ํ ์ ์์ฃ . ๐
ํ๋ํ์ ์ฃผ์ ํน์ง:
- ๋ก์ปฌ ์ด๋๋ฆฌ์ ๋คํธ์ํฌ ๊ตฌ์ถ ๊ฐ๋ฅ
- ์๋ฆฌ๋ํฐ ์ปดํ์ผ ์ง์
- ํ ์คํธ ์๋ํ ๊ธฐ๋ฅ
- ๋๋ฒ๊น ๋๊ตฌ ์ ๊ณต
- ํ๋ฌ๊ทธ์ธ ์์คํ ์ผ๋ก ํ์ฅ์ฑ ๋์
ํ๋ํ์ ๋ง์น ์ค์์ค ๊ตฐ์ฉ ์นผ ๊ฐ์์. ์ฌ๋ฌ ๊ฐ์ง ๊ธฐ๋ฅ์ด ์์ด์ ์ค๋งํธ ์ปจํธ๋ํธ ๊ฐ๋ฐ์ ๋ชจ๋ ๋จ๊ณ์์ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์์ฃ . ํนํ ์ค๋ ์ฐ๋ฆฌ๊ฐ ์ง์ค์ ์ผ๋ก ๋ณผ 'ํ ์คํธ ์๋ํ' ๊ธฐ๋ฅ์ ์ ๋ง ๋๋ฐ์ด์์! ๐
๊ทธ๋ฐ๋ฐ ๋ง์ด์์, ์ฌ๋ฌ๋ถ. ํน์ ์ฌ๋ฅ๋ท์ด๋ผ๋ ์ฌ์ดํธ ์์ธ์? ์ด ์ฌ์ดํธ์์๋ ๋ค์ํ ์ฌ๋ฅ์ ๊ฑฐ๋ํ ์ ์๋๋ฐ, ๋ธ๋ก์ฒด์ธ ๊ฐ๋ฐ ๊ด๋ จ ์ฌ๋ฅ๋ ๊ฑฐ๋๋๊ณ ์๋๋ผ๊ณ ์. ๋์ค์ ์ฌ๋ฌ๋ถ์ด ํ๋ํ ๋ง์คํฐ๊ฐ ๋๋ฉด ๊ฑฐ๊ธฐ์ ์ฌ๋ฅ ๋๋์ ํด๋ณด๋ ๊ฒ๋ ์ข์ ๊ฒ ๊ฐ์์! ๐
์ด์ ํ๋ํ์ด ๋ญ์ง ๋์ถฉ ๊ฐ์ด ์ค์๋์? ๊ทธ๋ผ ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ํ๋ํ์ ์ด์ฉํ ์ค๋งํธ ์ปจํธ๋ํธ ํ ์คํธ ์๋ํ์ ๋ํด ์์๋ณผ๊น์? ๐
๐ ๏ธ ํ๋ํ ์ค์นํ๊ณ ํ๋ก์ ํธ ์์ํ๊ธฐ
์, ์ด์ ํ๋ํ์ ์ค์นํด๋ณผ ๊ฑฐ์์. ๊ฑฑ์ ๋ง์ธ์, ์ด๋ ต์ง ์์์! ๊ทธ๋ฅ ๋ช ๊ฐ์ง ๋ช ๋ น์ด๋ง ์ ๋ ฅํ๋ฉด ๋ผ์. ๋ง์น ๊ฒ์ ์นํธํค ์ ๋ ฅํ๋ ๊ฒ์ฒ๋ผ์! ใ ใ ใ
๋จผ์ , Node.js๊ฐ ์ค์น๋์ด ์์ด์ผ ํด์. ์๋ค๋ฉด Node.js ๊ณต์ ์ฌ์ดํธ์์ ๋ค์ด๋ฐ์ ์ค์นํด์ฃผ์ธ์.
๊ทธ ๋ค์, ํฐ๋ฏธ๋(๋งฅOS) ๋๋ ๋ช ๋ น ํ๋กฌํํธ(์๋์ฐ)๋ฅผ ์ด๊ณ ๋ค์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํด์ฃผ์ธ์:
npm install --save-dev hardhat
์ด๋ ๊ฒ ํ๋ฉด ํ๋ํ์ด ์ค์น๋ผ์. ์ฝ์ฃ ? ๐
์ด์ ํ๋ํ ํ๋ก์ ํธ๋ฅผ ์์ํด๋ณผ๊น์? ๋ค์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํด์ฃผ์ธ์:
npx hardhat
๊ทธ๋ฌ๋ฉด ์ฌ๋ฌ ๊ฐ์ง ์ต์ ์ด ๋์ฌ ํ ๋ฐ, "Create a JavaScript project"๋ฅผ ์ ํํด์ฃผ์ธ์. ๊ทธ๋ฆฌ๊ณ ๋๋จธ์ง ์ง๋ฌธ๋ค์๋ ๊ทธ๋ฅ ์ํฐ๋ฅผ ๋๋ฌ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ ํ๋ฉด ๋ผ์.
๐ ์ถํํด์! ์ด์ ํ๋ํ ํ๋ก์ ํธ๊ฐ ์์ฑ๋์์ด์!
ํ๋ก์ ํธ ํด๋์ ๋ค์๊ณผ ๊ฐ์ ํ์ผ๋ค์ด ์๊ฒผ์ ๊ฑฐ์์:
- hardhat.config.js: ํ๋ํ ์ค์ ํ์ผ
- contracts/: ์ค๋งํธ ์ปจํธ๋ํธ ํ์ผ๋ค์ด ์ ์ฅ๋ ํด๋
- scripts/: ๋ฐฐํฌ ์คํฌ๋ฆฝํธ ๋ฑ์ด ์ ์ฅ๋ ํด๋
- test/: ํ ์คํธ ํ์ผ๋ค์ด ์ ์ฅ๋ ํด๋
์ด์ ์ฐ๋ฆฌ๋ ํ๋ํ์ ์ธ๊ณ์ ์ฒซ ๋ฐ์ ๋ด๋์์ด์! ์ด๋์? ์๊ฐ๋ณด๋ค ์ด๋ ต์ง ์์ฃ ? ์ด์ ๋ถํฐ๊ฐ ์ง์ง ์ฌ๋ฏธ์๋ ๋ถ๋ถ์ด์์. ์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ๋ง๋ค๊ณ ํ ์คํธํ๋ ๊ณผ์ ์ ๋ฐฐ์๋ณผ ๊ฑฐ์์. ๐
์, ์ด์ ์ฐ๋ฆฌ์ ์ฒซ ์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ๋ง๋ค์ด๋ณผ ์ค๋น๊ฐ ๋์๋์? ๋ค์ ์น์ ์์๋ ๊ฐ๋จํ ์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ์์ฑํ๊ณ , ๊ทธ๊ฒ์ ํ ์คํธํ๋ ๋ฐฉ๋ฒ์ ์์๋ณผ ๊ฑฐ์์. ๊ธฐ๋๋์ง ์๋์? ๐
๊ทธ๋ฆฌ๊ณ ์ ๊น! ํน์ ์ด๋ฐ ๊ฐ๋ฐ ์ง์์ ๋ค๋ฅธ ์ฌ๋๋ค๊ณผ ๋๋๊ณ ์ถ์ผ์ ๊ฐ์? ์ฌ๋ฅ๋ท์์ ์ฌ๋ฌ๋ถ์ ํ๋ํ ์ง์์ ๊ณต์ ํด๋ณด๋ ๊ฒ์ ์ด๋จ๊น์? ๋๊ตฐ๊ฐ์๊ฒ๋ ์ ๋ง ์์คํ ์ ๋ณด๊ฐ ๋ ์ ์์ ๊ฑฐ์์! ๐ก
๐ ์ฒซ ์ค๋งํธ ์ปจํธ๋ํธ ์์ฑํ๊ธฐ
์, ์ด์ ์ฐ๋ฆฌ์ ์ฒซ ์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ๋ง๋ค์ด๋ณผ ๊ฑฐ์์. ์์ฒญ ๋ณต์กํ ๊ฑฐ ์๋์์, ๊ฑฑ์ ๋ง์ธ์! ์์ฃผ ๊ฐ๋จํ ํ ํฐ ์ปจํธ๋ํธ๋ฅผ ๋ง๋ค์ด๋ณผ ๊ฑฐ์์. ์ด ์ปจํธ๋ํธ๋ ํ ํฐ์ ๋ฐํํ๊ณ , ์ ์กํ๊ณ , ์์ก์ ํ์ธํ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง ๊ฑฐ์์. ๐
๋จผ์ , contracts
ํด๋์ SimpleToken.sol
์ด๋ผ๋ ํ์ผ์ ๋ง๋ค์ด์ฃผ์ธ์. ๊ทธ๋ฆฌ๊ณ ๋ค์ ์ฝ๋๋ฅผ ์
๋ ฅํด์ฃผ์ธ์:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleToken {
string public name;
string public symbol;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
constructor(string memory _name, string memory _symbol, uint256 _totalSupply) {
name = _name;
symbol = _symbol;
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
}
function transfer(address _to, uint256 _amount) public returns (bool success) {
require(balanceOf[msg.sender] >= _amount, "Insufficient balance");
balanceOf[msg.sender] -= _amount;
balanceOf[_to] += _amount;
return true;
}
}
์ฐ์! ๐ฒ ์ด๊ฒ ๋ญ๊ฐ ์ถ์ฃ ? ์ฒ์ฒํ ์ค๋ช ํด๋๋ฆด๊ฒ์.
SimpleToken ์ปจํธ๋ํธ ์ค๋ช :
name
: ํ ํฐ์ ์ด๋ฆsymbol
: ํ ํฐ์ ์ฌ๋ณผ (์: BTC, ETH)totalSupply
: ์ด ๋ฐํ๋balanceOf
: ๊ฐ ์ฃผ์์ ํ ํฐ ์์ก์ ์ ์ฅํ๋ ๋งคํconstructor
: ์ปจํธ๋ํธ ๋ฐฐํฌ ์ ์คํ๋๋ ์์ฑ์ ํจ์transfer
: ํ ํฐ์ ๋ค๋ฅธ ์ฃผ์๋ก ์ ์กํ๋ ํจ์
์ด ์ปจํธ๋ํธ๋ ์ ๋ง ๊ฐ๋จํ์ง๋ง, ๊ธฐ๋ณธ์ ์ธ ํ ํฐ์ ๊ธฐ๋ฅ์ ๋ชจ๋ ๊ฐ์ถ๊ณ ์์ด์. ํ ํฐ์ ์ด๋ฆ๊ณผ ์ฌ๋ณผ์ ์ค์ ํ ์ ์๊ณ , ์ด ๋ฐํ๋์ ์ ํ ์ ์์ด์. ๊ทธ๋ฆฌ๊ณ ๊ฐ์ฅ ์ค์ํ ๊ธฐ๋ฅ์ธ ์ ์ก ๊ธฐ๋ฅ๋ ์์ฃ !
ํนํ transfer
ํจ์๋ฅผ ๋ณด์ธ์. ์ด ํจ์๋ ํ ํฐ์ ๋ค๋ฅธ ์ฃผ์๋ก ๋ณด๋ด๋ ์ญํ ์ ํด์. ๋จผ์ ๋ณด๋ด๋ ์ฌ๋์ ์์ก์ด ์ถฉ๋ถํ์ง ํ์ธํ๊ณ (require
๋ฌธ), ๊ทธ ๋ค์์ ์์ก์ ์ฐจ๊ฐํ๊ณ ๋ฐ๋ ์ฌ๋์ ์์ก์ ์ฆ๊ฐ์ํค์ฃ . ๊ฐ๋จํ์ง๋ง ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ด์์! ๐
์ด๋์? ์๊ฐ๋ณด๋ค ์ด๋ ต์ง ์์ฃ ? ์ด์ ์ฐ๋ฆฌ๋ ์์ฃผ ๊ธฐ๋ณธ์ ์ธ ํ ํฐ ์ปจํธ๋ํธ๋ฅผ ๋ง๋ค์์ด์. ์ด ์ปจํธ๋ํธ๋ก ์ฐ๋ฆฌ๋ง์ ๊ฐ์ํํ๋ฅผ ๋ง๋ค ์ ์๋ค๊ณ ์๊ฐํ๋ฉด ๋๊ฒ ์ฃ ? ใ ใ ใ
ํ์ง๋ง ์ ๊น! ๐ค ์ด ์ปจํธ๋ํธ๊ฐ ์ ๋๋ก ์๋ํ ๊น์? ์ฐ๋ฆฌ๊ฐ ์๋ํ ๋๋ก ๋์ํ ๊น์? ์ด๋ฐ ์๋ฌธ์ ํด๊ฒฐํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ ํ ์คํธ๋ฅผ ํด์ผ ํด์. ๊ทธ๋ฆฌ๊ณ ๋ฐ๋ก ์ฌ๊ธฐ์ ํ๋ํ์ ์ง๊ฐ๊ฐ ๋๋ฌ๋์ฃ !
๋ค์ ์น์
์์๋ ์ด SimpleToken
์ปจํธ๋ํธ๋ฅผ ํ
์คํธํ๋ ๋ฐฉ๋ฒ์ ์์๋ณผ ๊ฑฐ์์. ํ๋ํ์ ์ด์ฉํด์ ์๋ํ๋ ํ
์คํธ๋ฅผ ์์ฑํ๊ณ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณผ ๊ฑฐ์์. ์ ๋ง ์ ๋์ง ์๋์? ๐
๊ทธ๋ฆฌ๊ณ ํน์ ์ด๋ฐ ์ค๋งํธ ์ปจํธ๋ํธ ๊ฐ๋ฐ์ ๊ด์ฌ ์๋ ์น๊ตฌ๋ค ์๋์? ์ฌ๋ฅ๋ท์์ ์ฌ๋ฌ๋ถ์ ์ง์์ ๋๋๋ฉด ์ด๋จ๊น์? ๋๊ตฐ๊ฐ์๊ฒ๋ ์ ๋ง ๊ฐ์ง ์ ๋ณด๊ฐ ๋ ์ ์์ ๊ฑฐ์์! ๐ก
๐งช ํ๋ํ์ผ๋ก ์ค๋งํธ ์ปจํธ๋ํธ ํ ์คํธํ๊ธฐ
์, ์ด์ ์ง์ง ๊ฟ์ผ ํํธ๊ฐ ์์ด์! ์ฐ๋ฆฌ๊ฐ ๋ง๋ SimpleToken
์ปจํธ๋ํธ๋ฅผ ํ
์คํธํด๋ณผ ๊ฑฐ์์. ํ๋ํ์ ์ฌ์ฉํ๋ฉด ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์คํํ๋ ๊ฒ ์ ๋ง ์ฌ์์. ๋ง์น ๋ ๊ณ ๋ธ๋ก ์กฐ๋ฆฝํ๋ฏ์ด ํ
์คํธ๋ฅผ ๋ง๋ค ์ ์์ฃ ! ๐
๋จผ์ , test
ํด๋์ SimpleToken.test.js
ํ์ผ์ ๋ง๋ค์ด์ฃผ์ธ์. ๊ทธ๋ฆฌ๊ณ ๋ค์ ์ฝ๋๋ฅผ ์
๋ ฅํด๋ณผ๊ฒ์:
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("SimpleToken", function () {
let SimpleToken;
let simpleToken;
let owner;
let addr1;
let addr2;
beforeEach(async function () {
SimpleToken = await ethers.getContractFactory("SimpleToken");
[owner, addr1, addr2] = await ethers.getSigners();
simpleToken = await SimpleToken.deploy("Simple Token", "SIM", 1000000);
await simpleToken.deployed();
});
it("Should set the right owner", async function () {
expect(await simpleToken.owner()).to.equal(owner.address);
});
it("Should assign the total supply of tokens to the owner", async function () {
const ownerBalance = await simpleToken.balanceOf(owner.address);
expect(await simpleToken.totalSupply()).to.equal(ownerBalance);
});
it("Should transfer tokens between accounts", async function () {
// Transfer 50 tokens from owner to addr1
await simpleToken.transfer(addr1.address, 50);
const addr1Balance = await simpleToken.balanceOf(addr1.address);
expect(addr1Balance).to.equal(50);
// Transfer 50 tokens from addr1 to addr2
await simpleToken.connect(addr1).transfer(addr2.address, 50);
const addr2Balance = await simpleToken.balanceOf(addr2.address);
expect(addr2Balance).to.equal(50);
});
it("Should fail if sender doesn't have enough tokens", async function () {
const initialOwnerBalance = await simpleToken.balanceOf(owner.address);
// Try to send 1 token from addr1 (0 tokens) to owner (1000000 tokens).
// `require` will evaluate false and revert the transaction.
await expect(
simpleToken.connect(addr1).transfer(owner.address, 1)
).to.be.revertedWith("Insufficient balance");
// Owner balance shouldn't have changed.
expect(await simpleToken.balanceOf(owner.address)).to.equal(
initialOwnerBalance
);
});
});
์ฐ์! ์ด๊ฒ ๋ญ๊ฐ ์ถ์ฃ ? ใ ใ ใ ์ฒ์ฒํ ์ค๋ช ํด๋๋ฆด๊ฒ์. ๐
ํ ์คํธ ์ฝ๋ ์ค๋ช :
describe
: ํ ์คํธ ๊ทธ๋ฃน์ ์ ์ํด์.beforeEach
: ๊ฐ ํ ์คํธ ์ ์ ์คํ๋๋ ์ฝ๋์์. ์ฌ๊ธฐ์๋ ์ปจํธ๋ํธ๋ฅผ ๋ฐฐํฌํ๊ณ ์์ด์.it
: ๊ฐ๋ณ ํ ์คํธ ์ผ์ด์ค๋ฅผ ์ ์ํด์.expect
: ํ ์คํธ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ ํจ์์์.
์ด ํ ์คํธ ์ฝ๋๋ ์ฐ๋ฆฌ์ SimpleToken ์ปจํธ๋ํธ๊ฐ ์ ๋๋ก ์๋ํ๋์ง ํ์ธํ๊ณ ์์ด์. ๊ตฌ์ฒด์ ์ผ๋ก ๋ค์ ์ฌํญ๋ค์ ํ ์คํธํ๊ณ ์์ฃ :
- ์ปจํธ๋ํธ ์์ ์๊ฐ ์ ๋๋ก ์ค์ ๋์๋์ง
- ์ด ๊ณต๊ธ๋์ด ์์ ์์๊ฒ ํ ๋น๋์๋์ง
- ํ ํฐ ์ ์ก์ด ์ ๋๋ก ์๋ํ๋์ง
- ์์ก์ด ๋ถ์กฑํ ๋ ์ ์ก์ด ์คํจํ๋์ง
์ด์ ์ด ํ ์คํธ๋ฅผ ์คํํด๋ณผ๊น์? ํฐ๋ฏธ๋์์ ๋ค์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํด์ฃผ์ธ์:
npx hardhat test
๊ทธ๋ฌ๋ฉด ํ๋ํ์ด ์ฐ๋ฆฌ์ ํ ์คํธ๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ค ๊ฑฐ์์. ๋ง์ฝ ๋ชจ๋ ํ ์คํธ๊ฐ ํต๊ณผํ๋ค๋ฉด, ์ถํํด์! ๐ ์ฐ๋ฆฌ์ SimpleToken ์ปจํธ๋ํธ๊ฐ ์ ๋๋ก ์๋ํ๋ค๋ ๋ป์ด์์!
์ด๋์? ์๊ฐ๋ณด๋ค ์ด๋ ต์ง ์์ฃ ? ์ด๋ ๊ฒ ํ๋ํ์ ์ฌ์ฉํ๋ฉด ์ค๋งํธ ์ปจํธ๋ํธ ํ ์คํธ๋ฅผ ์๋ํํ ์ ์์ด์. ๋งค๋ฒ ์๋์ผ๋ก ํ ์คํธํ ํ์ ์์ด, ํ ๋ฒ์ ๋ช ๋ น์ด๋ก ๋ชจ๋ ํ ์คํธ๋ฅผ ์คํํ ์ ์์ฃ . ์ด๊ฒ ๋ฐ๋ก ํ๋ํ์ ๊ฐ๋ ฅํ ์ฅ์ ์ด์์! ๐
์ด๋ฐ ์๋ํ๋ ํ ์คํธ๋ ๊ฐ๋ฐ ๊ณผ์ ์์ ์ ๋ง ์ค์ํด์. ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ ๋๋ง๋ค ๋ชจ๋ ๊ธฐ๋ฅ์ด ์ฌ์ ํ ์ ๋๋ก ์๋ํ๋์ง ๋น ๋ฅด๊ฒ ํ์ธํ ์ ์๊ฑฐ๋ ์. ์ด๋ ๋ฒ๊ทธ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ๊ณ ์์ ํ๋ ๋ฐ ํฐ ๋์์ด ๋ผ์.
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฌ๋ถ, ํน์ ์ด๋ฐ ์๊ฐ ๋ค์ง ์๋์? "์, ์ด๋ฐ ๊ฑธ ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์๊ฒ๋ ์๋ ค์ฃผ๊ณ ์ถ๋ค!" ๊ทธ๋ ๋ค๋ฉด ์ฌ๋ฅ๋ท์ ํ์ฉํด๋ณด๋ ๊ฑด ์ด๋จ๊น์? ์ฌ๋ฌ๋ถ์ ํ๋ํ ํ ์คํธ ๋ ธํ์ฐ๋ฅผ ๊ณต์ ํ๋ฉด, ๋ง์ ๊ฐ๋ฐ์๋ค์๊ฒ ๋์์ด ๋ ๊ฑฐ์์. ๐
๐ ํ๋ํ ํ ์คํธ ์๋ํ์ ์ฅ์
์, ์ด์ ์ฐ๋ฆฌ๋ ํ๋ํ์ผ๋ก ์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ํ ์คํธํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ด์. ๊ทธ๋ฐ๋ฐ ์ ์ด๋ ๊ฒ ํ ์คํธ ์๋ํ๊ฐ ์ค์ํ ๊น์? ํ๋ฒ ์์ธํ ์์๋ณผ๊น์? ๐ค
ํ๋ํ ํ ์คํธ ์๋ํ์ ์ฃผ์ ์ฅ์ :
- ์๊ฐ ์ ์ฝ: ์๋ ํ ์คํธ ๋๋น ์์ฒญ๋ ์๊ฐ ์ ์ฝ
- ์ผ๊ด์ฑ: ํญ์ ๋์ผํ ์กฐ๊ฑด์์ ํ ์คํธ ๊ฐ๋ฅ
- ๋ฐ๋ณต ๊ฐ๋ฅ์ฑ: ์ธ์ ๋ ์ฝ๊ฒ ํ ์คํธ ๋ฐ๋ณต ๊ฐ๋ฅ
- ์ ๋ขฐ์ฑ: ์ฌ๋์ ์ค์๋ฅผ ์ค์ด๊ณ ์ ๋ขฐํ ์ ์๋ ๊ฒฐ๊ณผ ์ ๊ณต
- ๋น ๋ฅธ ํผ๋๋ฐฑ: ์ฝ๋ ๋ณ๊ฒฝ ์ ์ฆ์ ์ํฅ ํ์ธ ๊ฐ๋ฅ
์ด๋ฐ ์ฅ์ ๋ค ๋๋ถ์ ํ๋ํ์ ์ด์ฉํ ํ ์คํธ ์๋ํ๋ ์ค๋งํธ ์ปจํธ๋ํธ ๊ฐ๋ฐ์ ํ์ ์์๊ฐ ๋์์ด์. ํนํ ๋ธ๋ก์ฒด์ธ์ ํน์ฑ์ ํ๋ฒ ๋ฐฐํฌ๋ ์ปจํธ๋ํธ๋ ์์ ์ด ์ด๋ ต๊ธฐ ๋๋ฌธ์, ๋ฐฐํฌ ์ ์ฒ ์ ํ ํ ์คํธ๊ฐ ์ ๋ง ์ค์ํ์ฃ !
์๋ฅผ ๋ค์ด๋ณผ๊น์? ์ฐ๋ฆฌ๊ฐ ๋ง๋ SimpleToken ์ปจํธ๋ํธ์ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค๊ณ ํด๋ด์. ์๋ํ๋ ํ ์คํธ๊ฐ ์๋ค๋ฉด ๋งค๋ฒ ์๋์ผ๋ก ๋ชจ๋ ๊ธฐ๋ฅ์ ํ ์คํธํด์ผ ํด์. ์์ฒญ ์๊ฐ ๋ญ๋น์ฃ ! ๐ซ
ํ์ง๋ง ํ๋ํ์ผ๋ก ํ
์คํธ๋ฅผ ์๋ํํ๋ค๋ฉด? ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ณ npx hardhat test
๋ช
๋ น์ด ํ๋๋ง ์
๋ ฅํ๋ฉด ๋! ๋ช ์ด ๋ง์ ๋ชจ๋ ํ
์คํธ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์ด์. ์์ ๊ฐ์ด๋! ๐
๊ทธ๋ฆฌ๊ณ ๋ ํ๋! ํ ์คํธ ์๋ํ๋ ํ ํ์ ์๋ ํฐ ๋์์ด ๋ผ์. ๋ค๋ฅธ ๊ฐ๋ฐ์๊ฐ ์ฝ๋๋ฅผ ์์ ํ์ ๋, ์๋ํ๋ ํ ์คํธ๋ฅผ ํตํด ๊ธฐ์กด ๊ธฐ๋ฅ์ ๋ฌธ์ ๊ฐ ์๋์ง ๋น ๋ฅด๊ฒ ํ์ธํ ์ ์๊ฑฐ๋ ์. ์ด๋ฐ ๊ฒ ๋ฐ๋ก "์์ ๋ง" ์ญํ ์ ํ๋ ๊ฑฐ์ฃ ! ๐
์, ์ด๋ ์ธ์? ํ๋ํ์ ์ด์ฉํ ํ ์คํธ ์๋ํ์ ๋งค๋ ฅ์ ํน ๋น ์ง์ จ๋์? ์ด์ ์ฌ๋ฌ๋ถ๋ ํ๋ํ ๋ง์คํฐ์ ๊ธธ๋ก ํ ๋ฐ์ง ๋ค๊ฐ์ฐ์ด์! ๐
๊ทธ๋ฆฌ๊ณ ์์ง ๋ง์ธ์, ์ฌ๋ฌ๋ถ์ ์ด๋ฐ ๋ ธํ์ฐ๋ ์ ๋ง ๊ฐ์ง ๊ฑฐ์์. ์ฌ๋ฅ๋ท์์ ์ฌ๋ฌ๋ถ์ ํ๋ํ ํ ์คํธ ์๋ํ ๊ฒฝํ์ ๊ณต์ ํด๋ณด๋ ๊ฑด ์ด๋จ๊น์? ๋๊ตฐ๊ฐ์๊ฒ ์ ๋ง ์์คํ ์ ๋ณด๊ฐ ๋ ์ ์์ ๊ฑฐ์์! ๐ก
๐ ํ๋ํ ํ ์คํธ ์๋ํ ์ฌํ ๊ณผ์
์, ์ด์ ์ฐ๋ฆฌ๋ ํ๋ํ์ผ๋ก ๊ธฐ๋ณธ์ ์ธ ํ ์คํธ๋ฅผ ์์ฑํ๊ณ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ด์. ํ์ง๋ง ์ฌ๊ธฐ์ ๋ฉ์ถ๋ฉด ์ ๋ผ์! ๋ ๊น์ด ๋ค์ด๊ฐ ๋ณผ๊น์? ๐
ํ๋ํ์ ์ ๋ง ๊ฐ๋ ฅํ ํ ์คํธ ๊ธฐ๋ฅ๋ค์ ์ ๊ณตํด์. ๊ทธ ์ค ๋ช ๊ฐ์ง๋ฅผ ์๊ฐํด๋๋ฆด๊ฒ์:
ํ๋ํ์ ๊ณ ๊ธ ํ ์คํธ ๊ธฐ๋ฅ:
- ๊ฐ์ค ์ฌ์ฉ๋ ์ธก์
- ์๊ฐ ์กฐ์ (๋ธ๋ก ํ์์คํฌํ ๋ณ๊ฒฝ)
- ๋คํธ์ํฌ ํฌํฌ
- ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง ๋ถ์
์ด ์ค์์ '๊ฐ์ค ์ฌ์ฉ๋ ์ธก์ '๊ณผ '์๊ฐ ์กฐ์'์ ๋ํด ์์ธํ ์์๋ณผ๊น์?
1. ๊ฐ์ค ์ฌ์ฉ๋ ์ธก์
์ด๋๋ฆฌ์์์ ๊ฐ์ค ๋น์ฉ์ ์ ๋ง ์ค์ํด์. ํ๋ํ์ ์ฌ์ฉํ๋ฉด ๊ฐ ํจ์๊ฐ ์ผ๋ง๋ ๋ง์ ๊ฐ์ค๋ฅผ ์ฌ์ฉํ๋์ง ์ฝ๊ฒ ์ธก์ ํ ์ ์์ด์. ๋ค์๊ณผ ๊ฐ์ด ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ฃ :
it("Should use less than 50000 gas for transfer", async function () {
const tx = await simpleToken.transfer(addr1.address, 50);
const receipt = await tx.wait();
expect(receipt.gasUsed).to.be.below(50000);
});
์ด ํ
์คํธ๋ transfer
ํจ์๊ฐ 50,000 ๊ฐ์ค ์ดํ๋ฅผ ์ฌ์ฉํ๋์ง ํ์ธํด์. ๋ง์ฝ ์ด ๊ฐ์ ๋์ด๊ฐ๋ฉด ์ต์ ํ๊ฐ ํ์ํ๋ค๋ ๊ฑธ ์ ์ ์์ฃ !
2. ์๊ฐ ์กฐ์
์ค๋งํธ ์ปจํธ๋ํธ์์ ์๊ฐ์ ์ค์ํ ์์์์. ์๋ฅผ ๋ค์ด, ํ ํฐ ์ ๊ธ ๊ธฐ๊ฐ์ด๋ ์ด์ ์ง๊ธ ์๊ธฐ ๋ฑ์ ํ ์คํธํ ๋ ์ ์ฉํ์ฃ . ํ๋ํ์ ์ฌ์ฉํ๋ฉด ๋ธ๋ก์ ํ์์คํฌํ๋ฅผ ์ฝ๊ฒ ์กฐ์ํ ์ ์์ด์:
it("Should allow withdrawal after 1 week", async function () {
await simpleToken.lock();
await ethers.provider.send("evm_increaseTime", [7 * 24 * 60 * 60]); // 1์ฃผ์ผ ์ฆ๊ฐ
await ethers.provider.send("evm_mine"); // ์ ๋ธ๋ก ์์ฑ
await expect(simpleToken.unlock()).to.not.be.reverted;
});
์ด ํ
์คํธ๋ ํ ํฐ ์ ๊ธ ํ 1์ฃผ์ผ์ด ์ง๋๋ฉด ์ ๊ธ ํด์ ๊ฐ ๊ฐ๋ฅํ์ง ํ์ธํด์. evm_increaseTime
์ผ๋ก ์๊ฐ์ ์๋น๊ธฐ๊ณ , evm_mine
์ผ๋ก ์ ๋ธ๋ก์ ์์ฑํ๋ ๊ฑฐ์ฃ .
์ด๋ฐ ๊ณ ๊ธ ํ ์คํธ ๊ธฐ๋ฅ๋ค์ ํ์ฉํ๋ฉด, ์ฌ๋ฌ๋ถ์ ์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ๋์ฑ ์ฒ ์ ํ๊ฒ ๊ฒ์ฆํ ์ ์์ด์. ์ค์ ํ๊ฒฝ์์ ๋ฐ์ํ ์ ์๋ ๋ค์ํ ์ํฉ์ ์๋ฎฌ๋ ์ด์ ํ๊ณ ํ ์คํธํ ์ ์์ฃ . ์ด๋ ๋ฒ๊ทธ๋ฅผ ์ฌ์ ์ ๋ฐฉ์งํ๊ณ , ๋ ์์ ์ ์ธ dApp์ ๋ง๋๋ ๋ฐ ํฐ ๋์์ด ๋ผ์.
์ด๋ ์ธ์? ํ๋ํ์ ์ธ๊ณ๊ฐ ์ ์ ๋ ํฅ๋ฏธ์ง์งํด์ง๊ณ ์์ง ์๋์? ๐
๊ทธ๋ฆฌ๊ณ ์์ง ๋ง์ธ์, ์ฌ๋ฌ๋ถ์ด ๋ฐฐ์ด ์ด ๊ณ ๊ธ ํ ์คํธ ๊ธฐ๋ฒ๋ค์ ์ ๋ง ๊ฐ์ง ์ง์์ด์์. ์ฌ๋ฅ๋ท์์ ์ด๋ฐ ๋ ธํ์ฐ๋ฅผ ๊ณต์ ํ๋ฉด, ๋ง์ ๊ฐ๋ฐ์๋ค์๊ฒ ๋์์ด ๋ ๊ฑฐ์์. ์ฌ๋ฌ๋ถ์ ๊ฒฝํ์ด ๋๊ตฐ๊ฐ์ ๊ฐ๋ฐ ์ฌ์ ์ ํฐ ํ์ด ๋ ์ ์๋ต๋๋ค! ๐ช
๐ ๋ง๋ฌด๋ฆฌ: ํ๋ํ์ผ๋ก ๋ ๋์ ๊ฐ๋ฐ์ ๋๊ธฐ
์, ์ฌ๋ฌ๋ถ! ์ฐ๋ฆฌ๋ ์ ๋ง ๋ฉ์ง ์ฌ์ ์ ํจ๊ป ํ์ด์. ํ๋ํ์ ์ด์ฉํ ์ค๋งํธ ์ปจํธ๋ํธ ํ ์คํธ ์๋ํ์ ์ธ๊ณ๋ฅผ ํํํ์ฃ . ์ฒ์์๋ ์ด๋ ค์ ๋ณด์์ง๋ง, ํ๋์ฉ ๋ฐฐ์๊ฐ๋ฉด์ ์ ์ ๋ ์ฌ๋ฏธ์์ด์ก์ฃ ? ๐
์ฐ๋ฆฌ๊ฐ ๋ฐฐ์ด ๋ด์ฉ์ ๊ฐ๋จํ ์ ๋ฆฌํด๋ณผ๊น์?
ํ๋ํ ํ ์คํธ ์๋ํ ์ ๋ฆฌ:
- ํ๋ํ ์ค์น ๋ฐ ํ๋ก์ ํธ ์ค์
- ๊ฐ๋จํ ์ค๋งํธ ์ปจํธ๋ํธ ์์ฑ
- ๊ธฐ๋ณธ์ ์ธ ํ ์คํธ ์ฝ๋ ์์ฑ
- ํ ์คํธ ์คํ ๋ฐ ๊ฒฐ๊ณผ ํ์ธ
- ๊ณ ๊ธ ํ ์คํธ ๊ธฐ๋ฅ ํ์ฉ (๊ฐ์ค ์ธก์ , ์๊ฐ ์กฐ์ ๋ฑ)
์ด ๋ชจ๋ ๊ณผ์ ์ ํตํด ์ฐ๋ฆฌ๋ ๋ ์์ ์ ์ด๊ณ ์ ๋ขฐํ ์ ์๋ ์ค๋งํธ ์ปจํธ๋ํธ๋ฅผ ๊ฐ๋ฐํ ์ ์๊ฒ ๋์์ด์. ์ด๋ ๊ณง ๋ ๋์ dApp, ๋ ์์ ํ ๋ธ๋ก์ฒด์ธ ์ํ๊ณ๋ก ์ด์ด์ง๋ ๊ฑฐ์ฃ !
ํ์ง๋ง ์ฌ๋ฌ๋ถ, ์ด๊ฒ ๋์ด ์๋์์. ๊ธฐ์ ์ ์ธ๊ณ๋ ๊ณ์ํด์ ๋ฐ์ ํ๊ณ ์์ด์. ํ๋ํ๋ ๊ณ์ ์๋ก์ด ๊ธฐ๋ฅ๋ค์ ์ถ๊ฐํ๊ณ ์์ฃ . ๊ทธ๋ฌ๋ ํญ์ ์๋ก์ด ๊ฒ์ ๋ฐฐ์ฐ๊ณ ์คํํด๋ณด๋ ์์ธ๊ฐ ํ์ํด์.
๊ทธ๋ฆฌ๊ณ ์์ง ๋ง์ธ์. ์ฌ๋ฌ๋ถ์ด ๋ฐฐ์ด ์ด ์ง์๋ค, ๊ฒฝํํ ์ด ๊ณผ์ ๋ค์ ์ ๋ง ์์คํด์. ์ด๋ฅผ ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค๊ณผ ๊ณต์ ํ๋ ๊ฒ, ๊ทธ๊ฒ ๋ฐ๋ก ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ๋ฅผ ๋์ฑ ํ์๋กญ๊ฒ ๋ง๋๋ ๊ธธ์ด์์.
ํน์ ์ฌ๋ฅ๋ท์ ํตํด ์ฌ๋ฌ๋ถ์ ํ๋ํ ๊ฒฝํ์ ๊ณต์ ํด๋ณด๋ ๊ฑด ์ด๋จ๊น์? ๋๊ตฐ๊ฐ์๊ฒ ์ ๋ง ๊ฐ์ง ์ ๋ณด๊ฐ ๋ ์ ์์ ๊ฑฐ์์. ์ฌ๋ฌ๋ถ์ ์์ ๋์์ด ๋๊ตฐ๊ฐ์ ํฐ ๋์ฝ์ด ๋ ์ ์๋ต๋๋ค! ๐ก
์, ์ด์ ์ฌ๋ฌ๋ถ์ ํ๋ํ ๋ง์คํฐ์ ๊ธธ์ ํ ๋ฐ์ง ๋ ๊ฐ๊น์์ก์ด์. ์์ผ๋ก๋ ๊ณ์ํด์ ๋ฐฐ์ฐ๊ณ , ์คํํ๊ณ , ๊ณต์ ํ๋ฉด์ ์ฑ์ฅํด ๋๊ฐ์ธ์. ์ฌ๋ฌ๋ถ์ ๋ฏธ๋๊ฐ ์ ๋ง ๊ธฐ๋๋ผ์! ๐๐๐
๊ทธ๋ผ ๋ค์์ ๋ ๋ค๋ฅธ ํฅ๋ฏธ์ง์งํ ์ฃผ์ ๋ก ๋ง๋์. ์ฌ๋ฌ๋ถ์ ๊ฐ๋ฐ ์ฌ์ ์ ํ์ด์ด ํจ๊ปํ๊ธฐ๋ฅผ! ํ์ดํ ! ๐
- ์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์ฌ๋ฅ๋ท์ ์ต์ AI ๊ธฐ์ ๊ณผ ๋ฒ๋ฅ ์ ๊ธฐ๋ฐํ์ฌ ์์ฌ์ ์ง์ ์ฌ์ฐ๊ถ์ ์ ๊ทน์ ์ผ๋ก ๋ณดํธํ๋ฉฐ,
๋ฌด๋จ ์ฌ์ฉ ๋ฐ ์นจํด ํ์์ ๋ํด ๋ฒ์ ๋์์ ํ ๊ถ๋ฆฌ๋ฅผ ๋ณด์ ํฉ๋๋ค.
ยฉ 2025 ์ฌ๋ฅ๋ท | All rights reserved.
๋๊ธ 0๊ฐ