ERC-20이란...
: 2015년 11월 Faban Vogelsteller 의 EIP-20 제안의 의하여 탄생하였으며, ERC-20은 이더리움 토큰에 대한 기준을 정의한 것이다.
Token Standard 은 아래와 같이 정의된다
function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)
event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
추상함수 같은 개념이라고 한다. (추상함수: 구현이 이루어지지않고 단지 그 함수의 이름만 가지고 있다는 뜻)
interface ERC20Interface {
function totalSupply() external view returns (uint256); // 총발행량
function balanceOf(address account) external view returns (uint256); // 잔고
function transfer(address recipient, uint256 amount) external returns (bool); // 송금
function approve(address spender, uint256 amount) external returns (bool); // 승인
function allowance(address owner, address spender) external view returns (uint256); // 허용
function transferFrom(address spender, address recipient, uint256 amount) external returns (bool); // 유저간 송금
dssd
interface ERC20Interface {
//...
event Transfer(address indexed from, address indexed to, uint256 amount);
event Transfer(address indexed spender, address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 oldAmount, uint256 amount);
}
Transfer 이벤트는 transfer함수가 실행될때마다 로그를 남기고, Approval 이벤트는 approve 함수가 실행 될 때 로그를 남긴다.
contract SimpleToken is ERC20Interface {
mapping (address => uint256) private _balances; // mapping으로 _balances의 msg.sender의 주소의 키값과 uint256의 밸류값을 맵핑(=사용자의 잔고)
mapping (address => mapping (address => uint256)) public _allowances; // 이중mapping으로, [owenr][spender] 의 갯수 (=상환금?)
uint256 public _totalSupply; // 총발행량
string public _name; // erc-20 토큰 이름
string public _symbol; // erc-20 토큰 심볼명
uint8 public _decimals; // 고정 소수점 'decimals = 18' 이 표준이라고함
constructor(string memory getName, string memory getSymbol) { //구조체
_name = getName;
_symbol = getSymbol;
_decimals = 18;
_totalSupply = 100000000e18;
_balances[msg.sender] = _totalSupply;
}
function name () public view returns (string memory) {
return _name;
}
function symbol() public view returns (string memory) {
return _symbol;
}
function decimals() public view returns (uint8) {
return _decimals;
}
function totalSupply() external view virtual override returns (uint256) {
return _totalSupply;
}
// virtual override 에 대해서 검색 해보자
function balanceOf(address account) external view virtual override returns (uint256) {
return _balances[account];
// account 계정이 가지고 있는 토큰의 수를 반환
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(msg.sender, recipient, amount); // 내부함수인 _transfer 를 실행시킨다.
emit Transfer(msg.sender, recipient, amount); // emit: 이벤트 실행을 하는 키워드로 transfer에 대한 이벤트를 발생시킨다.
return true;
}
function approve(address spender, uint amount) external virtual override returns (bool) {
uint256 currentAllownace = _allowances[msg.sender][spender];
require(currentAllownace >= amount, "ERC20: Transfer amount exceeds allowance");
_approve(msg.sender, spender, currentAllownace, amount);
return true;
}
Approve는 토큰의 권한을 넘겨주는 함수(성공/실패)
이 함수를 이용할 때는 반드시 Approval 이벤트 함수를 호출해야 한다.
function allowance(address owner, address spender) external view override returns (uint256) {
return _allowances[owner][spender];
}
허용된 토큰의 개수 (갯수)
function transferFrom(address sender, address recipient, uint256 amount) external virtual override returns (bool) {
_transfer(sender, recipient, amount);
emit Transfer(msg.sender, sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][msg.sender];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, msg.sender, currentAllowance, currentAllowance - amount);
return true;
}
해당 토큰의 권한을 이용해 거래를 하도록 만들어 주는 함수(성공/실패)
[msg.sender] 대행자, 생성된 컨트랙트 주소이고 sender 보낸사람이 허락을 해준 만큼만 recipient 받는사람에게 토큰을 이동시킨다.
_transfer 함수 실행 → Transfer 이벤트 실행 → _approve 함수 실행
- http://wiki.hash.kr/index.php/ERC-20
- https://ethereum.org/en/developers/docs/standards/tokens/erc-20/
- https://eips.ethereum.org/EIPS/eip-20
- address(0) 의미, https://stackoverflow.com/questions/48219716/what-is-address0-in-solidity