ERC20

이더리움에서 사용하는 (대체 가능한) 토큰(=Fungible Token, FT) 표준입니다. 

 

 

ERC20 Method

function name() public view returns (string)

ERC20 contract 에 설정된 토큰 이름(=name)을 반환하는 함수입니다. 보통 생성자(constructor)의 입력을 통해 설정합니다.


function symbol() public view returns (string)

ERC20 contract 에 설정된 토큰 심볼(=symbol)을 반환하는 함수입니다. 보통 생성자(constructor)의 입력을 통해 설정합니다.


function decimals() public view returns (uint8)

ERC20 contract 에 설정된 토큰 소수자릿수(=decimals)를 반환하는 함수입니다. 보통 생성자(constructor)의 입력을 통해 설정하거나, 생성시 별도로 설정하지 않는다면 많은 ERC20 에서 사용하는 18을 default 값으로 사용하는 경우가 일반적입니다.

 

function totalSupply() public view returns (uint256)

ERC20 contract 를 통해 발행된 총 토큰수량을 반환하는 함수입니다. 만약, ERC20 토큰이 운영 중에 추가된다면 추가수량만큼 증가된 총 토큰 수량이 반환됩니다. 예를 들어, 어떤 ERC20 토큰이 OpenZeppelin 에서 (개발자 편의를 위해 미리 템플릿을 만들어 제공하는) ERC20 contract 로 개발되었고, 이 contract 가 총 수량을 추가할 수 있는 함수(ex, _mint() 함수)가 public 하게 오픈되어 있다면, 이 함수를 통해 총 발행 수량을 늘릴 수 있고, 이렇게 변경된 총 발행수량은 totalSupply() 함수의 결과값으로 반환하게 됩니다.


function balanceOf(address _owner) public view returns (uint256 balance)

ERC20 토큰을 _owner 계정(=eoa)이 얼마나 보유했는지 수량을 반환하는 함수입니다. ERC20 contract 에는 아래와 같이 _balances 라는 (외부서 직접 접근 및 변경이 불가능한) private 변수가 정의되어 있습니다. 이 변수는 key-value 구조인 map 자료형을 사용하는데, key 값은 사용자의 eoa 를 address 자료형으로 저장하고, 해당 key 의 value 값은 토큰 수량을 uint256 자료형으로 저장하고 있습니다.

 

mapping(address account => uint256) private _balances;
(출처 : OpenZepplin)

 

사용자(=eoa)가 ERC20 토큰을 전송할 때마다 전송한 수량만큼 value 값이 변경됩니다. balanceOf() 함수는 _owner 계정을 key 값으로 조회하여 해당 value 값을 그대로 반환하는 처리를 수행합니다.


function transfer(address _to, uint256 _value) public returns (bool success)

ERC20 토큰을 to 주소로 value 수량만큼 전송하는 함수입니다. transfer() 함수는 아래와 같이 contract 내의 _transfer(from, to, value) 함수를 호출하며, 이때 from 위치에는 TX를 실행한 사용자의 eoa 를, to 위치에는 입력값 중 _to 주소값을, 그리고 value 위치에는 입력된 value 값을 사용하여 호출하게 됩니다.

 

address owner = _msgSender();
_transfer(owner, to, value);

(출처 : OpenZepplin)

 

_transfer() 함수는 ERC20 의 전송 처리를 담당하는 함수인데, 이 함수는 위에서 언급한 _balance 변수의 값을 변경시키며, _transfer() 에 입력된 from 을 key 값으로 조회하여 가져온 value 값을 증가시키고, _transfer() 에 입력된 to 를 key 값으로 조회하여 가져온 value 값을 감소시키는 작업을 수행하며, 이러한 숫자 변환 처리 자체가 전송 처리의 매커니즘을 만들게 됩니다.

 

function approve(address _spender, uint256 _value) public returns (bool success)

ERC20 contract 는 자신의 토큰을 자신이 전송하는 것이 아닌, 다른 사람이 자신을 대신해서 전송할 수 있도록 하는 매커니즘이 있습니다. 아래와 같이 _allowances 라는 private 변수가 정의되어 있는데, 이 변수는 이중 key-value 구조를 가집니다. key 값은 TX를 실행한 본인의 eoa가 저장되며, value 값에는 자신을 대신하여 전송을 허용할 사용자들의 주소 혹은 컨트랙트 주소와 얼마나 허용할지에 대한 수량이 저장하고 있습니다.

 

mapping(address account => mapping(address spender => uint256)) private _allowances;

(출처 : OpenZepplin)

 

만약, 사용자 A가 사용자 B와 사용자C에게 자신을 대신해서 각각 50개씩 전송하도록 허용하고 있다면, _allowances 에는 아래처럼 저장되어 있을 것입니다. (참고, 아래는 json 포멧으로 map 구조를 변환하여 작성한 것입니다.)

 

{ "사용자 A" : {  "사용자 B" :  50, "사용자 C" : 50 } }

 

위처럼 _allowances 변수가 설정되어 있을때, 사용자 B와 사용자 C는 각자 사용자 A를 대신하여 사용자 A가 보유한 토큰을 최대 50개씩 전송이 가능하게 됩니다.


function allowance(address _owner, address _spender) public view returns (uint256 remaining)

_owner 의 계정이 _spender 계정에게 (_owner 의 계정을 대신하여 _owner 의 계정소유의 토큰을) 얼마나 대신해서 전송하는 것을 허용할지에 대한 수량을 반환하는 함수입니다. allowance() 함수는 _allowances 변수에서 _owner 계정을 기준으로 key 값을 조회하고 _spender 값을 기준으로 value 값을 한번 더 (value 값 안에서 key 값으로) 조회하여 가져온 값(=허용수량)을 반환합니다.

 


function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)

ERC20 토큰을 to 주소로 value 수량만큼 전송하는 함수입니다. transferFrom() 함수는 transfer() 함수와 다르게 _from 값을 추가로 받습니다. 이 함수는 TX 를 실행한 자신을 대신하여 다른 사용자가 자신의 토큰을 전송하려할 때 사용되는 함수입니다. 아래는 transferFrom() 함수의 처리과정의 일부분이며, _allowances 변수와 참조하는 로직이 추가로 있다는 점이 transfer() 함수와 다릅니다.

 

address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);

(출처 : OpenZepplin)



_spendAllownace() 함수가 내부에서 호출되는 것을 볼 수 있는데, 이 함수는 from 계정이 spender 계정에 value 수량 이상을 허용하고 있는지 확인하는 과정과 (허용하고 있다면) _allowances 변수에서 from 계정이 spender 계정에 허용한 토큰 수량을 value 만큼 줄이는 과정이 포함되어 있습니다. 이 처리 과정 때문에 spender 는 허용된 수량만큼만 전송이 가능하게 됩니다.

 

 

ERC20 Event

event Transfer(address indexed _from, address indexed _to, uint256 _value)

ERC20 토큰이 전송하는 TX가 발생되는 경우 발생되는 event 입니다. 실제로 이 event 는 _balances 변수값이 변경될 때 발생됩니다.

 

event Approval(address indexed _owner, address indexed _spender, uint256 _value)

ERC20 토큰이 전송하는 TX가 발생되는 경우 발생되는 event 입니다. 실제로 이 event 는 _allowances 변수값이 변경될 때 발생됩니다.

 

 

Reference