일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- FormData()
- JWT 하드코딩
- 시퀄라이즈 기본설정
- 세션으로 로그인 구현
- css기초
- express router
- javascript기초
- 라우트 매개변수
- 블록 만들기
- buffer.from
- cookie-parser 만들어보기
- express.static
- node.js path
- OAuth 카카오
- JWT 만들어보기
- mysql wsl
- 라우터미들웨어 분리
- 비동기파일업로드
- useContext
- nodejs파일업로드
- express session
- express실행
- JWT 로그인 기능 구현
- ws 라이브러리
- 라우터 분리
- Uncaught Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>
- useEffect clean up
- 라우터와 미들웨어
- next 매개변수
- 아이디 중복체크기능
- Today
- Total
즐코
ERC-20 나만의 토큰 작성 / fallback, receive? / 이더로 토큰 사기 본문
이전 포스팅에서 ERC-20의 interface IERC20 과 이를 상속한 ERC20을 정리해보았다.
(이전 포스팅 : https://yjleekr.tistory.com/102?category=1284408 )
이 ERC20 규격을 바탕으로 나만의 토큰을 작성해보고자 한다.
나만의 토큰 - YjToken 작성해보기
1/ 우선 아래 두 사실을 인지하고 작성해야한다.
- 해당 스마트 컨트랙트를 배포함과 동시에 토큰이 발행(mint)된다. 즉, 스마트 컨트랙트 배포자가 토큰의 발행자 (owner)이다.
- 해당 토큰은 이더로 살 수 있는 토큰이다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "./ERC20.sol";
contract YjToken is ERC20 {
address public owner;
uint256 public ethCanBuy = 100;
constructor(string memory _name, string memory _symbol, uint256 _amount){
owner = msg.sender;
name = _name;
symbol = _symbol,
mint(_amount * (10 ** uint256(decimals))
}
}
1/ ERC20 상속받기
우선, ERC20 컨트랙트 파일을 import 해와서 상속(is) 해준다.
2/ 상태변수 추가
위에서 설명한대로 YjToken의 발행자는 YjToken 스마트컨트랙트를 배포한 자이다. 또한, 이 YjToken은 이더로 살 수 있다!
따라서, 상속한 ERC20에서 정의한 상태변수(속성) 이외에 발행자(owner)와 이더-Yj토큰의 교환비율, 즉 환율 (ethCanBuy) 도 상태변수에 추가해준다. 1이더로 100 토큰을 살 수 있다! ( 1 ETH === 100 YTK )
address public owner;
uint256 public ethCanBuy = 100;
3/ 토큰의 생성자 함수
ERC20에서 기본적으로 필요한 name, symbol 뿐만 아니라, 발급할 토큰양도 인자로 받아준다.
해당 스마트 컨트랙트를 배포한 자가 토큰 발행자(소유자)여야하기 때문에 owner는 msg.sender이다.
또한, 스마트 컨트랙트를 배포함과 동시에 토큰을 발행해야하므로 생성자 함수 상에서 ERC20에서 상속받은 mint 함수를 실행시켜준다.
Q1. 발행량(amount)에 10**decimals(10^18)를 곱해준 이유
: 보통 이더리움 상에서 거래 단위는 ether가 아니라 wei이기 때문에 1 token === 1wei 로 단위를 맞춰주기 위해서
Q2. decimals(18)를 uint256으로 형변환 해준 이유
: ERC20 상에서 decimals는 uint8 타입으로 선언한 반면, mint함수는 uint 즉, uint256을 리턴한다. 그렇기 때문에 mint 함수 실행 시 uint8과 amount를 곱한 값이 떨어져서 리턴값으로 잡아둔 uint256과 맞지 않으므로 에러가 발생한다. 그렇기에 uint8의 decimals를 uint256으로 형변환시켜서 mint 함수의 리턴값과 align해줘야한다.
constructor(string memory _name, string memory _symbol, uint256 _amount){
owner = msg.sender;
name = _name;
symbol = _symbol;
mint(_amount * (10 ** uint256(decimals)));
}
4/ 이더로 토큰 구매 가능하게끔 구현
해당 컨트랙트가 어떤 계정에서 이더를 받아서 토큰으로 교환해주기 위해선 익명함수란 개념을 알고 가야한다.
익명함수 - receive 와 fallback
솔리디티에서의 익명함수는 쉽게 말하자면 트랙잭션 상에 실행할 스마트컨트랙트 내용, 코드가 없을 때 자동으로 실행되는 함수이다.
이더리움 상의 본질적인 거래는 단순한 코인 송금보단 스마트 컨트랙트의 실행이다. 따라서, 컨트랙트 실행이 아닌 단순한 코인의 거래일 경우에 자동으로 실행되는 함수를 만들어 뒀다고 보면 된다. 그렇기 때문에 CA가 ETH를 받을 수 있는 상태가 되게끔 payable 속성이 따라 붙는다.
원래는 fallback 함수 하나만 있었는데, fallback과 receive로 좀 더 디테일하게 나눠졌다고 보면 된다.
- fallback : 누군가가 ether를 지불하면서 스마트 컨트랙트 내 함수를 실행시켰는데, 그 실행시킨 함수가 스마트 컨트랙트 내에 존재하지 않는 함수라면 fallback 이 발동한다. 여기서 fallback 내부적으로 payable(msg.sender).transfer(refund)와 같은 메소드로 컨트랙트 실행을 요청한 계좌에 다시 이더를 환불해주려는 기능이 있지 않을까 추측해본다..
- receive : 누군가가 단순히 CA에 ether를 지불했을 때 실행되는 함수라고 보면 된다.
즉, 이 receive 함수 내부에서 누군가 YjToken 컨트랙트 계정 (CA)으로 이더를 보내면 이걸 토큰으로 교환하여 주는 코드를 작성하면 된다.
receive() external payable {
require(msg.value != 0); // 0 이더를 보내도 트랜잭션이 실행되므로 이를 막기 위해서 조건을 걸어둠
uint amount = msg.value * ethCanBuy;
// ethCanBuy = 1 이더당 100토큰
// msg.value는 wei단위로 오기 때문에 amount는 10**18 * 100 = 10**20 일 것이다.
require(balances[owner] >= amount);
balances[owner] -= amount;
balances[msg.sender] += amount;
// 해당 CA로 이더를 보내는 사람이 발행자 본인일 경우 토큰 발행량을 늘려버리는 코드를 추가해보았다..
if(msg.sender == owner){
mint(amount);
}
emit Transfer(owner, msg.sender, amount);
}
5/ 배포 후 메타마스크로 확인해보기
3000 토큰을 발급하기로 한다 ! (3000 YTK)
// migration/3_deploy_YjToken.js
const YjToken = artifacts.require("YjToken");
module.exports = function (deployer) {
deployer.deploy(YjToken, "YjToken", "YTK", 3000);
};
truffle migration 후 받은 YjToken의 CA를 메타마스크 상의 토큰 가져오기에서 넣고 토큰을 가져온다
이 Account3이 토큰 발행자가 되어 3000 YTK 를 다 가져갔다.
다른 계정 (Account 4) 에서 이더로 토큰을 구매해본다.
아래 스크린샷 순서대로 1 이더를 보내니 100 토큰을 가지게 되었다!
총 발행량 유지를 위해 발행자 계정 (Account 3) 에선 100 토큰이 빠져 나갔다!
이때, receive 함수 내에 토큰 발행자가 토큰 CA 로 이더를 보낼 경우 발행량을 늘리는 함수를 추가해서 이것도 테스트 해보았다.
토큰 발행량을 다시 3000 으로 복구하였다!
'BlockChain' 카테고리의 다른 글
ERC-721 / NFT / Remix로 컨트랙트 배포 및 실행 테스트 (0) | 2022.07.27 |
---|---|
ether-token 스왑 / 토큰발행 컨트랙트+스왑전용 컨트랙트 (0) | 2022.07.25 |
ERC20 interface / ERC20 (0) | 2022.07.22 |
ETHER 전송을 위한 스마트 컨트랙트 작성 (payable) (0) | 2022.07.21 |
스마트 컨트랙트로 초간단 투표 dApp 만들기 (0) | 2022.07.20 |