ERC-20 이론부터 배포까지
ERC-20
(Ethereum Request for Comment 20), 20은 리퀘스트 숫자입니다. 이더리움 네트워크의 개선안을 제안하는EIPs(Ethereum Improvement Proposals)
에서 관리하는 공식 프로토콜입니다, ERC-20 은 비교적 간단한 이더리움 기반 토큰을 만들기 위한 규약을 의미합니다. ERC-20
을 사용하는 이유는 여러 종류의 토큰끼리 호환하기 위해서입니다.
즉, application와 contract가 상호작용하는 규약을 만드는 것을 목표로 합니다.
이더리움 블록체인을 기반으로 다양한 탈중화한 애플리케이션들이 작동할 수 있도록 고안된 하나의 플랫폼이며,
dApp들은 이러한 플랫폼에서 스마트 계약을 이용하여, 토큰을 발행할 수 있습니다. 또한 토큰은 계정 지갑에 존재하지 않으며, contract 내부에만 존재합니다.
ERC-20 생성
ERC-20의 생성
, ERC-20 토큰을 생성하려면, solidity
라는 문법을 알아야 하고, ERC-20 규약을 지켜서 배포해야 합니다.
ERC-20의 규약은 전체 공급량(totalSupply)
, 잔고(balanceOf)
, 전송(transferFrom)
, 승인(approve)
, 허용(allowance)
과 같이 포함되어야 합니다.
// totalSupply, 콘트랙트가 보유하고 있는 토큰의 전체 공급량을 전달
function totalSupply() public view returns (uint256)
// balanceOf, 함수가 호출이 되면, 매개변수로 받았던 주소의 잔고를 공개합니다.
function balanceOf(address _owner) public view returns (uint256 balance)
// transfer, 다른 사용자에게 전송하는 것
function transfer(address _to, uint256 _value) public returns (bool success)
// tranferForm, franfer와 차이점을 요구하는데,
// 차이점은 다른 누군가 또는 다른 콘트랙트에서 여러분을 대신하여 자금을
// 전송하도록 허락할 수 있습니다.
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
// approve, 스마트 콘트랙트가 잔고에서 인출할 수 있는 토큰 수량을 제한할 수 있습니다.
function address(address _spender, uint256 _value) public returns (bool success)
// allowance, approve와 함께 사용할 수 있으며, allowance는 토큰을 인출할 수 있는
// 갯 수를 확인할 수 있습니다.
function allowance(address _owner, address _spender) public view return (uint256 remaining)
Simple Token 해석
간단한 예제를 통해서 한번 Simple Token을 만들어보도록 합니다.
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.10;
// solidity interface는 사용할 함수의 형태를 의미한다.
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);
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);
}
// simpleToken에서 ERC20Interface 함수를 선언하고, 함수 내용은 simpleToken에서 작성
contract SimpleToken is ERC20Interface {
// mapping은 키와 값이 쌍으로 이루어진 해시 테이블
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) public _allowances;
// 변수 선언 - 타입 권한 변수명
uint256 public _totalSupply;
string public _name;
string public _symbol;
uint8 public _decimals;
// constructor는 계약서가 배포될 때 호출
// 계약서마다 1개만 생성가능
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;
}
/**
* symbol은 주로 이름을 줄여서 표현합니다.
* bitcoin을 btc로 부르른 것처럼 말이죠.
*/
function symbol() public view returns (string memory) {
return _symbol;
}
/*
*사용자 표현을 위한 소수 자릿수를 반환
* decimals가 10, token이 100이면,
* (100 / 10 ** 10)과 같습니다.
**/
function decimals() public view returns (uint8) {
return _decimals;
}
// 전채 발행량 return
function totalSupply() external view virtual override returns (uint256) {
return _totalSupply;
}
// 매개 변수로 받은 account
function balanceOf(address account) external view virtual override returns (uint256) {
return _balances[account];
}
// 내부 함수 _transfer를 먼저 사용하여, 유효성을 채킹을 합니다.
// 1. 유효한 주소인지
// 2. 요청한 수량이상 있는지
// 그리고 정상적으로 해결되면
// emit으로 Transfer event 실행
// The Transfer Event 문서 (https://ethereumdev.io/transfers-and-approval-or-erc20-tokens-from-a-solidity-smart-contract/)
function transfer(address recipient, uint amount) public virtual override returns (bool) {
_transfer(msg.sender, recipient, amount);
emit Transfer(msg.sender, recipient, amount);
return true;
}
// 토큰을 인출할 수 있는 갯수 확인
// 내부함수 _approve를 통해서 확인후 승인
function allowance(address owner, address spender) external view override returns (uint256) {
return _allowances[owner][spender];
}
// 스마트 컨트랙트가 전송할 수 있는 토큰을 제한합니다.
// 1. 유효한 주소인지 확인.
// 2. emit
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;
}
// 이하로는 내부함수를 작성한 내용입니다.
// require은 오류를 체킹하여, 함수의 실행을 막는 역할을 합니다.
// emit은 Event 실행을 의미합니다.
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;
}
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
_balances[sender] = senderBalance - amount;
_balances[recipient] += amount;
}
function _approve(address owner, address spender, uint256 currentAmount, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
require(currentAmount == _allowances[owner][spender], "ERC20: invalid currentAmount");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, currentAmount, amount);
}
}
코드 작성을 완료 했습니다.
다음 편에는 직접적으로 배포하는 내용을 작성하겠습니다.
'etc > solidity' 카테고리의 다른 글
백신 did smart contract 만들어보기 (비교적 간단하게 - solidity) (0) | 2022.02.09 |
---|---|
ERC-721, NFT 뜻과 함수에 대해서 알아보자 (0) | 2022.01.21 |
solidity - 테스트넷 simple token 배포하기 - 2 / 2 편 (0) | 2022.01.20 |
솔리디티(solidity) 문법 (간단 정리) (0) | 2022.01.17 |