// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ERC20{
event Transfer();
event Approval();
function name() public view returns (string memory){
}
function symbol() public view returns (string memory){
}
function decimals() public view returns (uint8){
}
function totalSupply() public view returns (uint256){
}
function balanceOf(address account) public view returns (uint256){
}
function transfer(address to, uint256 amount) public returns (bool){
}
function allowance(address owner, address spender)public returns (uint256){
}
function approve(address spender, uint256 amount) public returns (bool){
}
function transferFrom(address from, address to, uint256 amount) public returns (bool){
}
}
// 사용자의 잔액 정보 관리를 하기 위한 mapping
mapping(address => uint) private _balances;
// 어느정도의 금액을 이동시킬 수 있는지 설정하기 위함
// _allowances 는 approve()와 transferFrom()으로 설정이된다.
mapping(address =>mapping(address=>uint)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
event Transfer( address indexed from, address indexed to, uint amount);
event Approval( address indexed from, address indexed to, uint amount);
constructor(string memory _name_, string memory _symbol_, uint8 _decimals){
_name = _name_;
_symbol = _symbol_;
_decimals = _decimals_;
_totalSupply = 10000000 * 10 **(18);
}
modifier checkBalance(uint amount){
require(_balances[msg.sender]> amount, "Not sufficient balance");
_;
}
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) returns (bool){
// 보내는 사람(컨트랙트를 호출한 사람)의 잔액이 충분한 양이 있는지 확인한다.
// require(_balances[msg.sender]> amount, "Not sufficient balance");
// approve()와 중복되기에 modifier를 사용해서 처리한다.
// balance의 값을 업데이트 시켜주는 형식
// 1. 보내는 사람(컨트랙트를 호출한 사람)의 잔액에서 요청한 잔액만큼 뺴준다.
_balances[msg.sender] -= amount;
// 2. 받는 사람 주소에 뺸만큼 더해주면 된다.
_balances[to] += amount;
// erc-20은 잔액관리를 CA에서 한다.
// 그래서 잔액정보가 업데이트만 된다.
// Transfer 함수가 실행되었음을 이벤트로 알린다
emit Transfer(msg.sender, to, amount);
// 성공하였으니 true 값 반환
return true;
}
function approve(address spender, uint256 amount) public checkBalance(amount) returns (bool){
// 권한을 허용할 만큼 내 잔액이 있는지 확인
//require(_balances[msg.sender]> amount, "Not sufficient balance");
// transfer()와 중복되기에 modifier를 사용해서 처리한다.
// 내 돈(msg.sender), 꺼내갈 수 있게 허락할 사람(spender), 꺼내갈 수 있는 금액
_allowances[msg.sender][spender] = amount;
// 이벤트로 기록
emit Approval(msg.sender, spender, amount);
// 성공하였으니 true
return true;
}
function allowance(address owner, address spender)public view returns (uint256){
return _allowances[owner][spender];
}
받는 사람이 일반적으로 호출한다.
// from이 to에게 돈을 보낼때
// 받는 사람이 일반적으로 호출한다.
function transferFrom(address from, address to, uint256 amount) public returns (bool){
// form이 가진 돈이 충분한 양인지 확인
require(_balances[from]> amount, "Not sufficient balance");
// 설정한 금액이 실제 전송하고자 하는 금액보다 많은지 확인
require(_allowances[from][to]>amount,"Not allowed amount");
// 허용을 요청한 사람이 msg.sender와 동일한지 확인(권한을 가진 사람이 요청을 하는지 확인)
require(to == msg.sender, "Not allowed user");
_balances[from] -= amount;
_balances[to] += amount;
// 이동되었음을 알리는 이벤트
emit Transfer(from, to, amount);
// 성공하였으니 true 값 반환
return true;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ERC20{
// 사용자의 주소와 잔액 정보 관리를 하기 위한 mapping
mapping(address => uint256) private _balances;
// 사용자가 내 돈을 다른 사용자에게 이동을 할 수 있는 권한을 주는 mapping
// 어느정도의 금액을 이동시킬 수 있는지 설정하기 위함
// _allowances 는 approve()와 transferFrom()으로 설정이된다.
mapping(address =>mapping(address=>uint256)) private _allowances;
// 토큰의 전체 발행량
uint256 private _totalSupply;
// 해당 토큰 컨트랙트의 명칭
string private _name;
// 해당 토큰의 심볼명
string private _symbol;
// 몇자리까지를 사용할 것인지(이더리움은 소수점 아래 18자리까지 사용한다.)
uint8 private _decimals;
// from이 to에게 얼마를 보냈는지 event상에서 기록해주기 위해 사용한다. indexed는 log상 데이터를 찾기 쉽게 하기 위해 사용
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");
_;
}
constructor(string memory _name_, string memory _symbol_, uint8 _decimals_){
_name = _name_;
_symbol = _symbol_;
_decimals = _decimals_;
_totalSupply = 10000000 * 10 **(18);
}
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) returns (bool){
// 보내는 사람(컨트랙트를 호출한 사람)의 잔액이 충분한 양이 있는지 확인한다.
// require(_balances[msg.sender]> amount, "Not sufficient balance");
// balance의 값을 업데이트 시켜주는 형식
// 1. 보내는 사람(컨트랙트를 호출한 사람)의 잔액에서 요청한 잔액만큼 뺴준다.
_balances[msg.sender] -= amount;
// 2. 받는 사람 주소에 뺸만큼 더해주면 된다.
_balances[to] += amount;
// erc-20은 잔액관리를 CA에서 한다.
// 그래서 잔액정보가 업데이트만 된다.
// Transfer 함수가 실행되었음을 이벤트로 알린다
emit Transfer(msg.sender, to, amount);
// 성공하였으니 true 값 반환
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) returns (bool){
// 권한을 허용할 만큼 내 잔액이 있는지 확인
// require(_balances[msg.sender]> amount, "Not sufficient balance");
// 내돈(msg.sender)을 다른사람이 얼마만큼 꺼내쓸수 있도록 권한 설정
// 내 돈(msg.sender), 꺼내갈 수 있게 허락할 사람(spender), 꺼내갈 수 있는 금액
_allowances[msg.sender][spender] = amount;
// 이벤트로 기록
emit Approval(msg.sender, spender, amount);
// 성공하였으니 true
return true;
}
// from이 to에게 돈을 보낼때
// 받는 사람이 일반적으로 호출한다.
function transferFrom(address from, address to, uint256 amount) public returns (bool){
// form이 가진 돈이 충분한 양인지 확인
require(_balances[from]> amount, "Not sufficient balance");
// 설정한 금액이 실제 전송하고자 하는 금액보다 많은지 확인
require(_allowances[from][to]>amount,"Not allowed amount");
// 허용을 요청한 사람이 msg.sender와 동일한지 확인(권한을 가진 사람이 요청을 하는지 확인)
require(to == msg.sender, "Not allowed user");
_balances[from] -= amount;
_balances[to] += amount;
// 이동되었음을 알리는 이벤트
emit Transfer(from, to, amount);
// 성공하였으니 true 값 반환
return true;
}
}
=====================
Deploying 'ERC20'
-----------------
> transaction hash: 0x426145b7e93d1c358bc75fc471f83754d15aa63aa9f37110eb1f26ce8bc6ec48
> Blocks: 0 Seconds: 0
> contract address: 0x07FCA98DB62Cd4CEc02B67a5d5A6924ab9f49832
> block number: 15064486
> block timestamp: 1673116729
> account: 0xDc45fE9fF7aF3522bB2B88a602670Ab4bE2C6f91
> balance: 9.861130299998611303
> gas used: 1009886 (0xf68de)
> gas price: 100.000000001 gwei
> value sent: 0 ETH
> total cost: 0.100988600001009886 ETH
> Saving artifacts
-------------------------------------
> Total cost: 0.100988600001009886 ETH
Summary
=======
> Total deployments: 1
> Final cost: 0.100988600001009886 ETH