ERC-20 구현

CHOYEAH·2023년 10월 23일
0
post-thumbnail

EIPs/eip-20.md at master · ethereum/EIPs

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

contract ERC20 {

  // 사용자 잔액정보
  mapping(address => uint) private _balances;

  // 특정 사용자에게 얼만큼의 토큰을 전송할 권한을 가지고있는지 관리하는..
  mapping(address => mapping(address=>uint)) private _allowances;

  // 블랙리스트
  mapping(address => bool) private _blackList;

  uint private _totalSupply;
  string private _name; // ETHEREUM
  string private _symbol; // ETH
  uint8 private _decimals;
  address public owner;

  // 로그상에서 쉽게 찾을 수 있도록 index를 설정 
  event Transfer(address indexed from, address indexed to, uint amount);
  event Approval(address indexed from, address indexed to, uint amount);

  modifier checkBalance(uint amount) {
    require(_balances[msg.sender] > amount, "Not sufficient Balance");
    _;
  }

  modifier onlyOwner() {
    require(msg.sender == owner, "Only owner");
    _;
  }

  modifier checkBlackList() {
    require(!_blackList[msg.sender], "Ban User");
    _;
  }

  constructor(string memory _name_, string memory _symbol_, uint8 _decimals_) {
    _name = _name_;
    _symbol = _symbol_;
    _decimals = _decimals_;
    _totalSupply = 10000000 * (10**18);
    owner = msg.sender;
  }

  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() public view returns (uint256) {
    return _totalSupply;
  }

  function balanceOf(address account) public view returns (uint256) {
    return _balances[account];
  }

  function transfer(address to, uint256 amount) public checkBalance(amount) checkBlackList returns (bool) {
    _balances[msg.sender] -= amount;
    _balances[to] += amount;

    emit Transfer(msg.sender, to, amount);
    return true;
  }

  function allowance(address _owner, address _spender) public view returns (uint256) {
    return _allowances[_owner][_spender];
  }

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

  function mint(address to, uint amount ) public onlyOwner{
    _balances[to] = amount;
    _totalSupply += amount;
  }

  function setBlackList(address to, bool tOrF) public onlyOwner {
    _blackList[to] = tOrF;
  }

  function burn(address to, uint amount) public onlyOwner {
    _balances[to] -= amount;
    _totalSupply -= amount;
  }

  function burnByUser(uint amount) public {
    // 없는 주소에 토큰을 전송하여 소각시킨다.
    transfer(address(0), amount);
    _totalSupply -= amount;
  }

  // 사용자 a가 사용자 b의 계좌에서 나에게 전송해달라고 요청하는 함수, 받는 사람이 호출하는 구조 
  function transferFrom(
    address from,
    address to,
    uint256 amount
  ) public  checkBlackList returns (bool) {
     require(_balances[from] > amount, "Not sufficient Balance");
     require(_allowances[from][to] > amount, "Not Allowed Amount");
     require(to == msg.sender, "Not Allowed Amount");

    _balances[from] -= amount;
    _balances[to] += amount;
    emit Transfer(from, to, amount);
    return true; 
  }

}
profile
Move fast & break things

0개의 댓글