Solidity语法基础学习
十、实战项目(二):
3.项目实操:
ERC20 代币实战
①转账篇
总发行量函数
totalSupply() return(uint256)
·回传代币的发行总量
·使用状态变量uint256_totalSupply来储存
账户余额查询函数
Balance0f(address) returns(uint256)
·给定一个账户(address),回传该账户拥有的代币余额(uint256)
·使用mapping来储存:
·mapping(address => uint256) _balance;
转账函数
Transfer(address,uint256) returns(bool);
·呼叫者“msg.sender”,转移“amount”数量的代币给特定账户“to”
·成功时回传true,反之,回传false
·有些检查需要做:
·amount是否超过余额
·是否转移给address 0x0代表销毁的意思
转账事件
event Transfer( address indexed from, address indexed to, uint256 value, );
·当发生代币转移时,必须触发此事件,即使转移的数量为“0”也是
②授权篇
授权余额查询函数
allowance(address owner,address spender) returns(uint256);
·给定两个账户(address),回传“owner”授权给“spender”的额度(uint256)
·使用mapping来储存:
·mapping(address =>
·mapping(address => uint256) _allowance;
注:mapping查询节省燃料
授权函数
approve(address spender,uint256 amount) returns(bool);
·呼叫者“msg.sender”,授权“amount”数量的代币额度给第三方账户“spender”
·成功时回传true,反之,回传false
授权事件
event Approval( address indexed owner, address indexed spender, uint256 value, );
·当授权额度时,必须触发此事件,即使数量为“0”也要触发
③花别人的钱
从第三方账户转账的函数
transferFrom(address from,address to,uint256 amount);
·呼叫者(msg.sender)从代币持有者(from)转账给接收者(to)“amount”数量的代币
·其中:
·需检查呼叫者是否拥有足够的额度可用
·转账时要检查持有者是否足够的余额
·转账时需要同时减少额度
4.补充概念:
ERC20代币实战
元资料(metadata)
铸造(mint)与销毁(burn)篇
ERC20 Meta接口
Interface IERCMetadata{……}
interface IERC20Metadata{ function name() public view returns(string memory); function symbol() public view returns(string memory); function decimals() public view returns(uint8); }
代币名称
function name() public view returns(string memory);
·回传一个字符,代表这个代币的名称
·储存是以string来保存
·通常在constructor的时候就给定
代币的简称/缩写/象征
function symbol() public view returns(string memory);
·回传一个字符串,代表这个代币的简称
·Ethereum(name)→ETH(symbol)
·Apple(name)→AAPL(symbol)
·储存时以string来保存
·通常在constructor的时候就给定
代币小数点位置
function decimals() public view returns(uint8);
·回传一个uint8,代表这个代币的小数点位置
·这个函数只用来显示用
·decimals=3,则balance=1234,在显示为1.234
·基本上代币都会把decimals设定为18
·这是因为最开始就是设计的18,后来因为人类天性,能抄就抄
·1ether=1018wei
·1token=1018uint => decimals=18
ERC20辅助函数
铸造(mint)与销毁(burn)
interface IERC20{ function mint(address account,uin256 amount); function burn(address account,uint256 amount); }
铸造新代币
function mint(address account,uint256 amount);
·铸造,即“无中生有”
·只有合约拥有者或者特殊权限的人才能呼叫
·他同时也是一种转账,由address 0x0转到目标账号(account)
·由于是转账,因此也要触发“Transfer”事件
销毁代币
function burn(address account,uint256 account);
·销毁,即“回归虚无”
·可以根据使用情况决定谁可以呼叫
·若只有合约拥有者可以呼叫,则通常会有account参数,用来销毁特定人的代币
·若任何人都可以呼叫,则不会有account参数,用来销毁特定人的代币
·若任何人都可以呼叫,则不会有account参数,主要目的是请求呼叫者(msg.sender)销毁自己的代币同时也是一种转账,由account/msg.sender转到address 0x0
·由于是转账,因此也要触发“Transfer”事件
Example:示例代码
//SPDX-License-Identifier:MIT pragma solidity ^0.8.17; interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner,address indexed spender, uint256 value); function totalSupply() external view returns (uint256); function balance0f(address account) external view returns (uint256); function allowance(address owner,address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transfer(address to, uint amount) external returns (bool); function trnasferFrom(address from, address to, uint256 amount) external returns (bool); } contract ERC20 is IERC20 { uint _totalSupply;//定义一个数 mapping(address => uint256) _balance;//定义了一个账号 mapping(address => mapping(address => uint256)) _allowance; //查询授权额度 function allowance(address owner, address spender) public view returns (uint256) { return _allowance[owner][spender];//返回自己和第三方 } function _approve(address owner, address spender, uint256 amount) internal { _allowance[owner][spender] = amount; emit Approval(owner, spender, amount); } //授权 function approve(address spender, uint256 amount) public returns (bool) { _approve(msg.sender, spender, amount); return true; } //发行代币,启动最初代币 constructor () { _balance[msg.sender] = 10000; _totalSupply = 10000; } function totalSupply() public view returns (uint256) { //回传总发行量 return _totalSupply; } function balance0f(address account) public view returns (uint256) { //回传查询余额 return _balance[account]; } function _transfer(address from, address to, uint256 amount) internal { uint256 myBalance = _balance[from]; require(myBalance >= amount,"No money to transfer!");//已经没钱转账了 require(to != address(0),"Transfer to address 0");//不准转账到地址0 _balance[from] = myBalance - amount;//我的账户总额计算 _balance[to] = _balance[to] + amount;//你的账户怎么计算 emit Transfer(from, to, amount); } //实现转账功能 function transfer(address to, uint256 amount) public returns (bool) { _transfer(msg.sender, to , amount); return true; } //检查额度花人家的钱 function trnasferFrom(address from, address to, uint256 amount) external returns (bool) { uint256 myAllowance = _allowance[from] [msg.sender]; require(myAllowance >= amount,"ERROR:myAllowance < amount"); //我们允许的额度是否小于了他花的额度 _approve(from, msg.sender, myAllowance - amount);//花去以后是否允许的额度有减少 _transfer(from, to, amount); //检查花销是否从原来账户转移到被授权者账户 return true; } }
标签:function,uint256,代币,solidity,returns,amount,address,特辑,区块 From: https://www.cnblogs.com/wybsignal/p/17062717.html