> For the complete documentation index, see [llms.txt](https://whs3-doge5k.gitbook.io/smartcontract-security-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://whs3-doge5k.gitbook.io/smartcontract-security-docs/basics/2./undefined-3/erc20.md).

# ERC20 개요 및 간단한 구현

ERC는 Ethereum Request for Comments의 약자이며, ERC-20은 2015년 제안된 토큰 인터페이스 표준 제안서 #20을 뜻한다.

* **ERC20**은 Ethereum 네트워크에서 대체 가능한 토큰(Fungible Token)을 구현하기 위한 **스마트 컨트랙트 표준이다.**&#x20;
* 다양한 **DeFi 앱**, **지갑**, **거래소**에서 ERC20 표준을 기반으로 토큰을 인식하고 처리한다.

## 핵심 인터페이스 함수

| 함수명                              | 설명           |
| -------------------------------- | ------------ |
| `totalSupply()`                  | 총 발행량 조회     |
| `balanceOf(address)`             | 특정 주소의 잔액 조회 |
| `transfer(to, amount)`           | 토큰 전송        |
| `approve(spender, amount)`       | 위임 승인        |
| `transferFrom(from, to, amount)` | 위임된 전송 실행    |
| `allowance(owner, spender)`      | 위임된 남은 양 조회  |

* 이 외에도 이벤트 Transfer, Approval이 필수로 포함되어야 하다.&#x20;

ERC20 예제문

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import "./IERC20.sol";

contract ERC20 is IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(
        address indexed owner, address indexed spender, uint256 value
    );

    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
    string public name;
    string public symbol;
    uint8 public decimals;

    constructor(string memory _name, string memory _symbol, uint8 _decimals) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
    }

    function transfer(address recipient, uint256 amount)
        external
        returns (bool)
    {
        balanceOf[msg.sender] -= amount;
        balanceOf[recipient] += amount;
        emit Transfer(msg.sender, recipient, amount);
        return true;
    }

    function approve(address spender, uint256 amount) external returns (bool) {
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount)
        external
        returns (bool)
    {
        allowance[sender][msg.sender] -= amount;
        balanceOf[sender] -= amount;
        balanceOf[recipient] += amount;
        emit Transfer(sender, recipient, amount);
        return true;
    }

    function _mint(address to, uint256 amount) internal {
        balanceOf[to] += amount;
        totalSupply += amount;
        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal {
        balanceOf[from] -= amount;
        totalSupply -= amount;
        emit Transfer(from, address(0), amount);
    }

    function mint(address to, uint256 amount) external {
        _mint(to, amount);
    }

    function burn(address from, uint256 amount) external {
        _burn(from, amount);
    }
}

```

요약하자면 아래와 같다.&#x20;

| 항목     | 설명                                                                             |
| ------ | ------------------------------------------------------------------------------ |
| ERC20  | 대체 가능한 토큰(Fungible Token)의 표준                                                  |
| 필수 함수  | `totalSupply`, `balanceOf`, `transfer`, `approve`, `transferFrom`, `allowance` |
| 필수 이벤트 | `Transfer`, `Approval`                                                         |
| 구현 방법  | 상태 변수, 매핑, 이벤트, 함수 모두 포함 필요                                                    |
| 테스트    | Foundry 환경에서 직접 테스트 가능                                                         |

출처 : <https://docs.openzeppelin.com/contracts/4.x/api/token/erc20>

<https://solidity-by-example.org/app/erc20/>
