赞
踩
erc20需要实现以下方法
- function name() public view returns (string)
- function symbol() public view returns (string)
- function decimals() public view returns (uint8)
- function totalSupply() public view returns (uint256)
- function balanceOf(address _owner) public view returns (uint256 balance)
- function transfer(address _to, uint256 _value) public returns (bool success)
- function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
- function approve(address _spender, uint256 _value) public returns (bool success)
- function allowance(address _owner, address _spender) public view returns (uint256 remaining)
以及两个事件
- event Transfer(address indexed _from, address indexed _to, uint256 _value)
- event Approval(address indexed _owner, address indexed _spender, uint256 _value)
一.name()
虚拟货币的名称,我们可以创建一个String变量,可见性设为public,由于public会自动创建一个getter方法,所以不需要再创建额外的name()方法
string public name = "NilahToken";
二.symbol()
名称缩写,原理如上,继续创建String变量
string public symbol = "NLT";
三.decimals()
虚拟货币小数点后的位数,一般都是18位
uint256 public decimals = 18;
四.totalSupply()
货币数量,但在此处是创建的一个getter方法,用于返回创建的货币的数量
uint256 public totalSupply;
五.balanceof()
用于返回一个账户所拥有的此货币的数量,我们可以用mapping映射,address映射uint256,继续public,自动创建getter方法
mapping (address => uint256) public balanceOf;
六.transfer()
转账方法,简单点来说就是加减,这里麻烦了一点,是调用了另一个函数
- function transfer(address _to, uint256 _value) public returns (bool success){
- require(_to != address(0));
- _transfer(msg.sender, _to, _value); //调用_transfer函数
- return true;
- }
七._transfer()
这是上面所调用的方法,这个方法有三个参数,_from从哪里转,_to转到哪里,_value转出数量
- function _transfer(address _from, address _to, uint256 _value) internal{ //私有函数 用于调用
- require(balanceOf[_from] >= _value);
- balanceOf[_from] = balanceOf[_from].sub(_value);
- balanceOf[_to] = balanceOf[_to].add(_value);
- emit Transfer(_from,_to,_value);
- }
require(balanceOf[_from] >= _value);
我们刚刚创建的映射balanceof,这里需要比较,balanceof[_from]为转出去的地址的余额,我要给_to转_value,那我的余额肯定得比_value多或者等于_value
- balanceOf[_from] = balanceOf[_from].sub(_value);
- balanceOf[_to] = balanceOf[_to].add(_value);
在转账成功过后,_from的账户肯定得减少_value,而收账的账户也得增加_value,这里的add与sub是调用了库里的方法,当然也可以不调用,简单粗暴的进行加减
emit Transfer(_from,_to,_value);
触发事件
七.transferFrom()
第三方转账,可以理解为平台交易,例如我给这个平台授权了多少代币,那么这个平台才可以使用多少代币
-
- function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
- //msg.sender提供授权的账户
- //_from交易所账户
- //_value金额
- require(balanceOf[_from] >= _value);
- require(allowance[_from][msg.sender] >= _value); //授权金额大于转账金额
- allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value); //授权金额减去转账金额
- _transfer(_from, _to, _value); //调用方法进行转账
- return true;
- }
这里面的allowance等会儿会提到
八.approve()
刚刚提到了第三方转账,转账的前提是需要授权,那么这个就是授权方法,添加一个映射用于存储账户所授权的值,在上一个方法中转账成功后,那么这值就会减少
- mapping (address => mapping (address => uint256)) public allowance;
- function approve(address _spender, uint256 _value) public returns (bool success){ //授权给交易所金额
- //msg.sender当前账户
- //_spender交易所地址
- //_value金额
- require(_spender != address(0));
- allowance[msg.sender][_spender] = _value; //msg.sender授权给_spender交易所_value金额
- emit Approval(msg.sender, _spender, _value);
- return true;
- }
由于刚刚的交易触发了两个事件,所以不要忘了把事件加上
- event Transfer(address indexed _from, address indexed _to, uint256 _value);
- event Approval(address indexed _owner, address indexed _spender, uint256 _value);
以下为完整代码
- pragma solidity >=0.4.16 <0.9.0;
- import "openzeppelin-solidity/contracts/math/SafeMath.sol";
- contract NilahToken{
- using SafeMath for uint256;
- string public name = "NilahToken";
- string public symbol = "NLT";
- uint256 public decimals = 18;
- uint256 public totalSupply;
- mapping (address => uint256) public balanceOf;
- mapping (address => mapping (address => uint256)) public allowance;
- event Transfer(address indexed _from, address indexed _to, uint256 _value);
- event Approval(address indexed _owner, address indexed _spender, uint256 _value);
-
-
- constructor() {
- totalSupply = 1000000 * (10 ** decimals);
- balanceOf[msg.sender] = totalSupply;
- }
-
-
- function transfer(address _to, uint256 _value) public returns (bool success){
- require(_to != address(0));
- _transfer(msg.sender, _to, _value); //调用_transfer函数
- return true;
- }
-
- function _transfer(address _from, address _to, uint256 _value) internal{ //私有函数 用于调用
- require(balanceOf[_from] >= _value);
- balanceOf[_from] = balanceOf[_from].sub(_value);
- balanceOf[_to] = balanceOf[_to].add(_value);
- emit Transfer(_from,_to,_value);
- }
-
- function approve(address _spender, uint256 _value) public returns (bool success){ //授权给交易所金额
- //msg.sender当前账户
- //_spender交易所地址
- //_value金额
- require(_spender != address(0));
- allowance[msg.sender][_spender] = _value; //msg.sender授权给_spender交易所_value金额
- emit Approval(msg.sender, _spender, _value);
- return true;
- }
-
- function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
- //msg.sender提供授权的账户
- //_from交易所账户
- //_value金额
- require(balanceOf[_from] >= _value);
- require(allowance[_from][msg.sender] >= _value); //授权金额大于转账金额
- allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value); //授权金额减去转账金额
- _transfer(_from, _to, _value); //调用方法进行转账
- return true;
- }
- }
1.规定版本
2.导入SafeMath库,方便后续使用sub、add方法
3.代码块里有注解
4.此代码复制粘贴即可使用,但是需要自行下载SafeMath库
5.代码名称以及代号在变量name和symbol处更改
6.Token位数可以在decimals处更改
7.存量是1000000,也可以在构造函数的totalSupply处更改
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。