무지개곰
article thumbnail
반응형

이더리움에서 가장 유명하면서도 널리 사용되는 토큰 표준 중 하나로 ERC20이 있습니다. ERC20을 따르면 자산을 보다 쉽게 교환할 수 있고 다양한 Dapp끼리 동일한 표준에 따라 상호 연동할 수 있습니다. ERC20 토큰을 생성하기 위하여 어떠한 규칙을 따라야 하는지 알아보겠습니다.

1. ERC20 표준

ERC20 토큰은 대체 가능 토큰(fungible token)으로 고유하지 않으면서 동일한 가치의 다른 토큰으로 완벽히 대체할 수 있는 토큰입니다. 따라서 ERC20 기반 토큰을 생성하려면 아래의 함수를 반드시 제공해야 합니다.

<bash />
totalSupply() balanceOf(address _owner) transfer(address _to, uint256 _value) transferFrom(address _from, address _to, uint256 _value) approve(address _spender, uint256 _value) allowance(address _owner, address _spender)

위에서부터 각 함수의 역할을 설명하자면 아래와 같습니다.

totalSupply는 토큰의 총 발행량

balanceOf는 _owner가 소지하고 있는 토큰의 수량 확인

transfer은 _to에게 _value만큼 토큰을 전송

transferFrom은 _from으로부터 _to에게 _value만큼 토큰 전달

approve는 _spender에게 _value만큼 토큰의 권한을 부여

allowance는 _owner가 _spender에게 권한을 부여한 토큰 수량 확인

 

또한 위의 함수 이외에도 사용되는 이벤트는 아래와 같습니다.

<bash />
transfer(address indexed _from, address indexed _to, uint256 _value) approval(address indexed _owner, address indexed _spender, uint256 _value)

토큰 전송 및 권한 부여를 하게 되면 두 이벤트를 발생시켜 로그에 기록합니다. 이를 통하여 토큰을 전송하였는지 권한을 부여하였는지 이벤트의 로그를 통하여 확인할 수 있습니다.


2. mint와 burn

mint 함수는 새로운 토큰을 발행하는 기능을 구현할 때 사용될 수 있습니다.

burn 함수는 특정 주소가 소유한 토큰을 감소시키는 역할을 합니다.

mint와 burn함수는 ERC-20 표준에서는 제공되지 않고, 프로젝트의 특정 요구에 따라 사용자 정의 함수로 구현되어야 합니다. 따라서 mint와 burn 기능이 필요한 경우, ERC-20 토큰을 개발하는 프로젝트에서는 해당 기능을 자체적으로 추가하여 스마트 계약을 구현해야 합니다. 이러한 기능을 구현하기 위해서는 프로젝트의 개발자가 토큰의 로직을 수정하고, mint와 burn 기능을 구현하는 함수를 추가하여야 합니다.

 

*Openzeppelin에서 제공하는 ERC20의 경우 _mint함수와 _burn함수가 존재합니다.

_mint

<bash />
function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); }

_burn

<bash />
function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); }

3. 최대 발행량 제한

bitcoin의 경우 총발행량이 2100만 개로 제한되어 있습니다. ERC-20을 이용하여 총발행량을 제한하려면 스마트 계약에서 해당 로직을 구현해야 합니다. 일반적으로 ERC-20 토큰의 총공급량은 totalSupply() 함수를 통해 조회하므로 다음과 같은 방법으로 토큰의 총발행량을 제한할 수 있습니다.

<bash />
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract RainbowBearToken is ERC20 { uint256 public maxSupply; constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) { maxSupply = 1000000; // 총 발행량을 1,000,000으로 설정 } function mint(address _to, uint256 _amount) public { require(totalSupply() + _amount <= maxSupply, "Max supply exceeded"); _mint(_to, _amount); emit Transfer(address(0), msg.sender, _amount); } }
  1. openzeppelin을 이용하여 ERC20을 import 합니다.
  2. import 한 ERC20을 is를 이용하여 RainbowBearToken에 상속합니다.
  3. constructor를 이용하여 maxSupply를 설정해 줍니다.
  4. 상속받은 ERC20도 선언을 하기 위하여 constructor의 매개변수인 _name과 _sybol을 ERC20(_name, _sybol)을 통하여 전달합니다.
  5. mint라는 함수를 만들고 require문을 통하여 총발행량을 확인 후 상속받은 ERC20의 함수인 _mint를 통하여 토큰을 발행합니다.
반응형

'BlockChain > solidity' 카테고리의 다른 글

[Solidity] ERC-2771이란? (ERC-2771Context란?)  (0) 2023.07.02
[Solidity] EIP-712란?  (0) 2023.07.02
[Solidity] ERC20 Permit이란?  (0) 2023.06.17
[Solidity] ERC-1155란?  (0) 2023.05.18
[Solidity] ERC-721이란?  (0) 2023.05.18
profile

무지개곰

@무지개곰

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!