以下是 ERC20 的應用,中心化交易所
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
// 運算過程中溢出(公開的類)
library SafeMath {
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= b);
return c;
}
}
interface IERC20 {
// 獲取地址
function getAddress() external view returns (address);
// 返回當前存在的Token的總單位。ERC20Token可以有固定或可變的供應量。
function totalSupply() external view returns (uint256);
// 根據地址獲取餘額(Token)
function balanceOf(address account) external view returns (uint256);
// 從哪到哪交易轉帳 recpient 接收地址
function transfer(address recipient, uint256 amount)
external
returns (bool);
// 給定一個所有者地址和一個消費者地址,返回該消費者被批准從所有者的取款的剩餘金額。
// 他能重我們的帳戶滑走多少錢
function allowance(address owner, address spender)
external
view
returns (uint256);
// 先批准,在滑轉 approve ->allowance
function approve(
address owner,
address spender,
uint256 amount
) external returns (bool);
// sender 發送者, recipient 接收者
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
// 日誌
event Transfer(address indexed from, address indexed to, uint256 value);
// 日誌
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
// 實現
contract ERC20Basic is IERC20 {
// 代幣名稱
string public constant name = "ERC20-TestToken";
// 代幣簡稱
string public constant symbol = "ERC-TTK";
uint8 public constant decimals = 18;
// 帳戶
mapping(address => uint256) balances;
// 二維錢
mapping(address => mapping(address => uint256)) allowed;
// ether 10*18 多少代幣
uint256 totalSupply_ = 10 ether;
using SafeMath for uint256;
// 構造函數
constructor() {
// 發行了多少錢給創建人(建立合約的人)
balances[msg.sender] = totalSupply_;
}
function getAddress() public view override returns (address) {
return address(this);
}
function totalSupply() public view override returns (uint256) {
return totalSupply_;
}
// 獲取餘額
function balanceOf(address tokenOwner)
public
view
override
returns (uint256)
{
return balances[tokenOwner];
}
// receiver 接收的人
function transfer(address receiver, uint256 numTokens)
public
override
returns (bool)
{
require(numTokens >= balances[msg.sender]);
// 轉出去的人
balances[msg.sender] = balances[msg.sender].sub(numTokens);
// 接收的人
balances[receiver] = balances[receiver].add(numTokens);
emit Transfer(msg.sender, receiver, numTokens);
return true;
}
function approve(
address owner,
address delegate,
uint256 numTokens
) public override returns (bool) {
// owner 底下的delegate允許滑走多少錢
allowed[owner][delegate] = numTokens;
emit Approval(owner, delegate, numTokens);
return true;
}
function allowance(address owner, address delegate)
public
view
override
returns (uint256)
{
return allowed[owner][delegate];
}
// owner 傳出去 buyer 接收者 多少錢
function transferFrom(
address owner,
address buyer,
uint256 numTokens
) public override returns (bool) {
require(numTokens <= balances[owner]);
require(numTokens <= allowed[owner][msg.sender]);
balances[owner] = balances[owner].sub(numTokens);
allowed[owner][buyer] = allowed[owner][buyer].sub(numTokens);
balances[buyer] = balances[buyer].add(numTokens);
emit Transfer(owner, buyer, numTokens);
return true;
}
}
// 中心化交易所
contract DEX {
event Bought(uint256 amount);
event Sold(uint256 amount);
IERC20 public token;
constructor() {
token = new ERC20Basic();
}
function buy() public payable {
uint256 amountTobuy = msg.value; // 買多少
// 合約多少錢
uint256 dexBalance = token.balanceOf(address(this)); //合約多少錢
require(amountTobuy > 0, "You need to send some Ether");
require(amountTobuy <= dexBalance, "Not enough tokens in the reserve");
token.transfer(msg.sender, amountTobuy);
emit Bought(amountTobuy);
}
function sell(uint256 amount) public {
require(amount > 0, "You need to sell at laeast some tokens");
uint256 allowance = token.allowance(msg.sender, address(this));
require(allowance >= amount, "Check the token allowance");
token.transferFrom(msg.sender, address(this), amount);
emit Sold(amount);
}
function getDexBalance() public view returns (uint256) {
return token.balanceOf(address(this));
}
// 現在這個人的代幣有多少
function getOwnerBalance() public view returns (uint256) {
return token.balanceOf(msg.sender);
}
function getAdress() public view returns (address) {
return address(this);
}
function getTokenAddress() public view returns (address) {
return token.getAddress();
}
function getTotalSupply() public view returns (uint256) {
return token.totalSupply();
}
function getSenderAddress() public view returns (address) {
return address(msg.sender);
}
function getAllowance() public view returns (uint256) {
uint256 allowance = token.allowance(msg.sender, address(this));
return allowance;
}
function approve(uint256 amount) public returns (bool) {
bool isApprove = token.approve(msg.sender, address(this), amount);
return isApprove;
}
}
SafeMath
這部分是防止計算中溢出(通常別人已經寫好不用再自己寫)有任何問題可反饋: [email protected]