토큰 컨트랙트 발행하기

GIWA에서 토큰 컨트랙트를 개발하고 배포하는 방법을 알아보세요.

ERC20이란?

ERC20은 Ethereum의 토큰 표준이며, ERC20 스마트 컨트랙트는 대체 가능한 토큰(Fungible Token)을 관리해요. 대체 가능한 토큰이란, 모든 토큰이 동일하고 어떤 토큰이라도 특별한 권한이나 동작을 가지지 않는 토큰을 의미해요. 즉, 누군가 소유한 1개의 토큰은 여러분이 가진 토큰 1개와 동일한 가치를 가지고 있어요. 이러한 특성 덕분에 ERC20 토큰은 교환 수단, 투표권, 스테이킹 등에 유용하게 활용될 수 있어요.

ERC20 표준은 스마트 컨트랙트가 구현해야 하는 6개의 필수 기능과 3개의 선택적 기능을 정의하고 있어요.

필수 기능은 아래와 같아요.

  • totalSupply: 토큰의 총 공급량을 정의하는 메서드예요.

  • balanceOf: 지갑 주소가 보유한 토큰 수를 반환하는 메서드예요.

  • transfer: 호출하는 사람으로부터 특정 양의 토큰을 다른 사용자에게 전달하는 메서드예요.

  • transferFrom: 사용자 간 토큰 전송에 사용되는 또 다른 유형의 전송 메서드예요. 이 메소드를 사용하면 토큰을 전송하려는 쪽에서 직접 호출하지 않아도 돼요. 하지만, 토큰을 받으려는 쪽은 토큰을 제공할 지갑 주소에서 allowance 범위 안에서만 전송 받을 수 있어요.

  • approve: 특정 사용자에게 일정량의 토큰을 사용할 수 있도록 미리 허락해두는 메서드예요.

  • allowance: 한 사용자가 다른 사용자에게 얼마만큼의 토큰을 전송하도록 허락해두었는지 확인할 수 있는 메소드예요.

위에 나열된 필수 기능 외에도 선택적 기능이 있으며, 이는 토큰의 사용성을 향상시켜요.

  • name: 토큰의 이름을 반환하는 메서드예요.

  • symbol: 토큰의 심볼을 반환하는 메서드예요.

  • decimals: 토큰이 사용하는 소수점 자릿수를 반환하는 메서드예요. 토큰의 최소 단위를 정의하는 데 사용돼요. 예를 들어, ERC20 토큰의 decimals 값이 6이라면, 이 토큰은 소수점 이하 6자리까지 나눌 수 있다는 걸 의미해요.

토큰을 ERC20 토큰으로 만들려면 ERC20 인터페이스를 구현해야 하고, 이는 반드시 이 6가지 메서드를 구현하도록 하고 있어요.


ERC20 컨트랙트 개발하기

Ethereum을 포함한 여러 블록체인에는 이미 다양한 그룹이 개발한 수많은 ERC20 호환 토큰이 운영 중이에요. 이러한 구현 방식은 가스 비용 절감에 중점을 두는 경우도 있고, 보안 강화에 우선순위를 두는 경우도 있어 다양해요.

견고하고 안전한 구현을 위해 많은 개발자들은 OpenZeppelin이나 Solady와 같은 스마트 컨트랙트 라이브러리를 사용해요. 이러한 라이브러리는 커뮤니티의 보안 감사를 거친 검증된 스마트 컨트랙트 라이브러리를 제공하고 있고, ERC20 토큰도 포함되어 있어 토큰 개발 시에 선호되는 선택지예요.

이번 예제에서는 OpenZepplin 라이브러리를 사용해서 ERC20 토큰 컨트랙트를 개발해볼까요?


개발 환경 세팅

  1. Foundry 를 설치해요.

curl -L https://foundry.paradigm.xyz | bash
foundryup

  1. Solidity Project 생성

forge init sample-token
cd sample-token

  1. OpenZepplin 라이브러리 설치

forge install OpenZeppelin/openzeppelin-contracts

컨트랙트 및 테스트 작성

src/SampleToken.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract SampleToken is ERC20 {
    uint256 public constant INITIAL_BALANCE = 1e24;

    constructor() ERC20("Sample", "SMP") {
        _mint(msg.sender, INITIAL_BALANCE);
    }
}

컨트랙트가 작성되었다면, 테스트 코드를 작성해서 의도한대로 컨트랙트가 작동하는지 확인할 수 있어요.

test/SampleToken.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {Test} from "forge-std/Test.sol";
import {SampleToken} from "src/SampleToken.sol";

contract SampleTokenTest is Test {
    SampleToken public token;

    function setUp() public {
        token = new SampleToken();
    }

    function test_initialBalance() public view {
        assertEq(token.balanceOf(address(this)), token.INITIAL_BALANCE());
    }

    function test_nameAndSymbol() public view {
        assertEq(token.name(), "Sample");
        assertEq(token.symbol(), "SMP");
    }
}

아래 명령어를 통해 컨트랙트를 빌드하고 테스트 할 수 있어요.

forge build
forge test

토큰 배포하기

배포 스크립트를 아래처럼 작성할 수 있어요.

script/Deploy.s.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {Script} from "forge-std/Script.sol";
import {SampleToken} from "src/SampleToken.sol";

contract DeploySampleToken is Script {
    function run() public {
        vm.startBroadcast();
        SampleToken token = new SampleToken();
        vm.stopBroadcast();
    }
}

배포 스크립트를 실행하고, Giwa Sepolia 테스트넷에서 실제로 스마트 컨트랙트를 배포하는 방법에 대해서는 여기에서 볼 수 있어요.

Last updated