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