猛戳订阅学习专栏🍁🍁 👉 solidity系列合约源码+解析 👈 🍁🍁
1 介绍ERC-20是一项以太坊代币标准,是从EIP-20提案经过以太坊社区不断讨论验证后通过而来的,是由Vitalik Buterin于2015年提出,是以太坊的第20号代币标准。
截止到我开始写本篇文章,以太坊上已存在536259种erc20代币合约,也就意味着共发行了这么多种erc20代币。
ERC-20代币是一种代币标准,由V神于2015年6月提出此标准,由Fabian Vogelsteller(erc20及erc725作者,也是LUKSO Token 创始人)于2015年11月提交EIP-20。该标准允许开发者在以太坊区块链网络上开发属于自己的代币,该标准定义了开发者可以按照标准要求使用一些简单的功能如:
设定代币名称设定代币总量规定小数点位数规范如何批准代币交易如何访问数据允许查看各地址中erc20代币数目以及代币总量一定条件下,允许第三方账户使用某账户中的代币资产允许代币和兼容ETH的智能合约及钱包服务等第三方个体兼容以及一些简单的函数功能等等。
我们先来看一下标准的 ERC20 标准的接口:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function name() constant returns (string name);
function symbol() constant returns (string symbol);
function decimals() constant returns (uint8 decimals);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
下面我们解释一下上述每个接口函数的作用:
event Transfer(address indexed from, address indexed to, uint256 value):
转账事件,当发生转账 *** 作时该event会被触发。所谓事件,其本质是记录的日志,当转账事件发生时,外界是无法监听相关数据的,即不知道转账发生了,此时的解决方法便是利用事件,将信息记录起来,外界通过监听事件来判断合约做了什么,因为事件本身的作用与目的,发送事件也被称为广播事件。
event Approval(address indexed owner, address indexed spender, uint256 value);
授权事件,当执行approve
*** 作时该event会被触发。
name ()
: 返回 string 类型的 ERC-20 代币的名称
symbol ()
: 返回 string 类型的 ERC-20 代币符号,可以理解为代币的简称
decimals ()
: 当前代币支持几位小数,如果为 3,则支持 0.001 粒度的代币。在智能合约里,其实是不存在小数的,而是通过 unit256 来存在,deciaml 用于表示 uint256 存储的值中有几位代表小数,常见的合约decimals为18。
totalSupply ()
: 代币总发行量
balanceOf(address account)
: account 地址中代币的余额
transfer(address to, uint256 amount)
: 转账函数,假设地址 A 调用了 transfer 函数,则表示将地址 A 中amount 个 token 转给地址to
approve(address spender, uint256 amount)
: 授权函数,允许spender 地址从自己的账户地址中转移amount 个 token(很多钓鱼网站使用的函数)
allowance(address owner, address spender)
返回spender 地址还能从owner 地址中提取多少 token,当合约通过 approve 函数获得某地址授权后,默认是可以转移该地址中所有的 token 的。
transferFrom(address from,address to,uint256 amount)
: 转账函数,与 approve 函数搭配使用,通过 approve 函数获得from 地址的授权,授权对象是当前调用 transferFrom 函数的合约地址,此时合约便可以转移from 地址中的amount 个 token 到to 地址中
ERC-20 标准中,transfer、approve、transferFrom 这三者是比较容易搞混的函数,这里简单解释一下:
transfer(address to, uint256 amount) 是单纯的转账,假设账户 A 调用了 transfer 函数给账户 B 转账,形式为:transfer (B, 100),该函数的会检查 A 地址中是否有 100 个相关代币,如果有,则将 100 个代币转到 B 地址中。
transferFrom(address from,address to,uint256 amount)是替别人转账,假设账户 A 中有 100 个代币,账户 A 同样想转给账户 B,但他不想直接转,此时便出现了账户 C(通常是一个合约),合约 C 会通过 approve 函数获得 *** 作账户 A 中代币的授权,然后合约 C 通过 transferFrom 函数将账户 A 中的 100 个代币转移给账户 B。
你可能会疑惑,转账为啥要还要引入合约 C 这个第三方?直接用 transfer 函数转账不行吗?
只使用 tranfer 函数进行转账是没有问题的,但并不能满足所有的情况,比如 DeFi 的各种借贷应用,本质还是将账户 A 的代币转给账户 B,但账户 A 之所以会借是因为有借出去的代币可以产生利息收益,这个功能就需要一个独立于账户 A 与账户 B 之外的合约 C 来实现,比如 Uniswap 就会获取你账户中代币的 *** 作权限。
这些复杂的业务场景我们在后面的文章中会有相应的合约示例讲解。
3 代码示例在实际的合约开发中我们并不需要去实现每一个方法,因为现在已经有很多开源的智能合约库帮我们实现了基本的方法,而且他们实现的合约代码都经过了权威审计单位的审计,比我们一个个去实现要安全许多,我们就没必要重复造轮子了,要学会站在巨人的肩膀。
本篇文章使用到的智能合约开发库:
openzeppelin
有兴趣的同学可以去看一下他们的源码。
下面让我们来写一个基础的ERC20合约:
// SPDX-License-Identifier: MIT;
pragma solidity 0.8.7;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Erc20T is ERC20{
constructor(uint _totalSuperNum) ERC20("T test","T") {
_mint(msg.sender,_totalSuperNum);
}
}
是的,你没有看错,就单单使用了一个构造方法我们就实现了一个ERC20代币合约,下面让我们来看一下传入的相关参数:
_totalSuperNum :为合约部署时要传入的铸造代币的数量T test : 为合约部署后产生代币的名称T :为合约部署后产生代币的简写,也就是代币符号(类似USDT) 4 部署测试可以分别查看合约部署代币的名称、简写、总量、相应地址的代币余额等。。。
好了,我们solidity实现智能合约教程的ERC20篇就到此结束了,后面会更新更加复杂业务类型的合约,欢迎关注~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)