스마트 컨트랙트와 ERC-20 개발

Yona·2022년 1월 19일
1

블록체인

목록 보기
15/22
post-thumbnail

introduction

Achievement Goals

  • ERC-20과 FT를 이해할 수 있다.
  • ERC-20에 포함된 함수별 기능을 이해할 수 있다.
  • ERC-20 스마트 컨트랙트를 테스트넷에 배포할 수 있다.
  • 공개된 ERC-20의 코드를 분석할 수 있다.
  • ERC-20 개발 환경을 적절히 사용할 수 있다.
  • Truffle로 ERC-20을 구현할 수 있다.
  • 구현한 ERC-20 스마트 컨트랙트를 Ganache에 배포할 수 있다.
  • Truffle과 Remix에서 OpenZeppelin 라이브러리를 사용할 수 있다.
  • 클레이튼 개발 환경을 구축할 수 있다.
    ~~- KaiKas 지갑과 Klaytn IDE를 사용할 수 있다.
  • 클레이튼 기반의 FT를 배포할 수 있다.~~

⚙️ ERC-20

ERC-20이란...

: 2015년 11월 Faban VogelstellerEIP-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

추상함수 같은 개념이라고 한다. (추상함수: 구현이 이루어지지않고 단지 그 함수의 이름만 가지고 있다는 뜻)

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;
    }

⚙️ name 함수 - 토큰 이름

  function name () public view returns (string memory) {
    return _name;
  }

⚙️ sysmbol 함수 - 토큰 심볼

  function symbol() public view returns (string memory) {
    return _symbol;
}

⚙️ decimals 함수 - 고정 소수점

  function decimals() public view returns (uint8) {
    return _decimals;
  }

⚙️ totalSupply 함수 - 총 발행량

  function totalSupply() external view virtual override returns (uint256) { 
    return _totalSupply;
  }

// virtual override 에 대해서 검색 해보자

⚙️ balanceOf 함수 - 잔고

  function balanceOf(address account) external view virtual override returns (uint256) {
    return _balances[account];

// account 계정이 가지고 있는 토큰의 수를 반환

⚙️ transfer 함수 - 송금

  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;
    }

⚙️ approve 함수 - 승인

  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 이벤트 함수를 호출해야 한다.

⚙️ allowance 함수 - 허용

  function allowance(address owner, address spender) external view override returns (uint256) {
    return _allowances[owner][spender];
    }

허용된 토큰의 개수 (갯수)

⚙️ transferFrom함수 - 사용자 간 송금

  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

0개의 댓글