当前位置:   article > 正文

ERC20-创建属于自己的虚拟货币_怎么创建erc20钱包

怎么创建erc20钱包

erc20需要实现以下方法

  1. function name() public view returns (string)
  2. function symbol() public view returns (string)
  3. function decimals() public view returns (uint8)
  4. function totalSupply() public view returns (uint256)
  5. function balanceOf(address _owner) public view returns (uint256 balance)
  6. function transfer(address _to, uint256 _value) public returns (bool success)
  7. function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
  8. function approve(address _spender, uint256 _value) public returns (bool success)
  9. function allowance(address _owner, address _spender) public view returns (uint256 remaining)

以及两个事件

  1. event Transfer(address indexed _from, address indexed _to, uint256 _value)
  2. 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()

        转账方法,简单点来说就是加减,这里麻烦了一点,是调用了另一个函数

  1. function transfer(address _to, uint256 _value) public returns (bool success){
  2. require(_to != address(0));
  3. _transfer(msg.sender, _to, _value); //调用_transfer函数
  4. return true;
  5. }

七._transfer()

        这是上面所调用的方法,这个方法有三个参数,_from从哪里转,_to转到哪里,_value转出数量

  1. function _transfer(address _from, address _to, uint256 _value) internal{ //私有函数 用于调用
  2. require(balanceOf[_from] >= _value);
  3. balanceOf[_from] = balanceOf[_from].sub(_value);
  4. balanceOf[_to] = balanceOf[_to].add(_value);
  5. emit Transfer(_from,_to,_value);
  6. }
require(balanceOf[_from] >= _value);

        我们刚刚创建的映射balanceof,这里需要比较,balanceof[_from]为转出去的地址的余额,我要给_to转_value,那我的余额肯定得比_value多或者等于_value

  1. balanceOf[_from] = balanceOf[_from].sub(_value);
  2. balanceOf[_to] = balanceOf[_to].add(_value);

        在转账成功过后,_from的账户肯定得减少_value,而收账的账户也得增加_value,这里的add与sub是调用了库里的方法,当然也可以不调用,简单粗暴的进行加减

emit Transfer(_from,_to,_value);

        触发事件

七.transferFrom()

        第三方转账,可以理解为平台交易,例如我给这个平台授权了多少代币,那么这个平台才可以使用多少代币

  1. function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
  2. //msg.sender提供授权的账户
  3. //_from交易所账户
  4. //_value金额
  5. require(balanceOf[_from] >= _value);
  6. require(allowance[_from][msg.sender] >= _value); //授权金额大于转账金额
  7. allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value); //授权金额减去转账金额
  8. _transfer(_from, _to, _value); //调用方法进行转账
  9. return true;
  10. }

        这里面的allowance等会儿会提到

八.approve()

        刚刚提到了第三方转账,转账的前提是需要授权,那么这个就是授权方法,添加一个映射用于存储账户所授权的值,在上一个方法中转账成功后,那么这值就会减少

  1. mapping (address => mapping (address => uint256)) public allowance;
  2. function approve(address _spender, uint256 _value) public returns (bool success){ //授权给交易所金额
  3. //msg.sender当前账户
  4. //_spender交易所地址
  5. //_value金额
  6. require(_spender != address(0));
  7. allowance[msg.sender][_spender] = _value; //msg.sender授权给_spender交易所_value金额
  8. emit Approval(msg.sender, _spender, _value);
  9. return true;
  10. }

由于刚刚的交易触发了两个事件,所以不要忘了把事件加上

  1. event Transfer(address indexed _from, address indexed _to, uint256 _value);
  2. event Approval(address indexed _owner, address indexed _spender, uint256 _value);

以下为完整代码

  1. pragma solidity >=0.4.16 <0.9.0;
  2. import "openzeppelin-solidity/contracts/math/SafeMath.sol";
  3. contract NilahToken{
  4. using SafeMath for uint256;
  5. string public name = "NilahToken";
  6. string public symbol = "NLT";
  7. uint256 public decimals = 18;
  8. uint256 public totalSupply;
  9. mapping (address => uint256) public balanceOf;
  10. mapping (address => mapping (address => uint256)) public allowance;
  11. event Transfer(address indexed _from, address indexed _to, uint256 _value);
  12. event Approval(address indexed _owner, address indexed _spender, uint256 _value);
  13. constructor() {
  14. totalSupply = 1000000 * (10 ** decimals);
  15. balanceOf[msg.sender] = totalSupply;
  16. }
  17. function transfer(address _to, uint256 _value) public returns (bool success){
  18. require(_to != address(0));
  19. _transfer(msg.sender, _to, _value); //调用_transfer函数
  20. return true;
  21. }
  22. function _transfer(address _from, address _to, uint256 _value) internal{ //私有函数 用于调用
  23. require(balanceOf[_from] >= _value);
  24. balanceOf[_from] = balanceOf[_from].sub(_value);
  25. balanceOf[_to] = balanceOf[_to].add(_value);
  26. emit Transfer(_from,_to,_value);
  27. }
  28. function approve(address _spender, uint256 _value) public returns (bool success){ //授权给交易所金额
  29. //msg.sender当前账户
  30. //_spender交易所地址
  31. //_value金额
  32. require(_spender != address(0));
  33. allowance[msg.sender][_spender] = _value; //msg.sender授权给_spender交易所_value金额
  34. emit Approval(msg.sender, _spender, _value);
  35. return true;
  36. }
  37. function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
  38. //msg.sender提供授权的账户
  39. //_from交易所账户
  40. //_value金额
  41. require(balanceOf[_from] >= _value);
  42. require(allowance[_from][msg.sender] >= _value); //授权金额大于转账金额
  43. allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value); //授权金额减去转账金额
  44. _transfer(_from, _to, _value); //调用方法进行转账
  45. return true;
  46. }
  47. }

1.规定版本

2.导入SafeMath库,方便后续使用sub、add方法

3.代码块里有注解

4.此代码复制粘贴即可使用,但是需要自行下载SafeMath库

5.代码名称以及代号在变量name和symbol处更改

6.Token位数可以在decimals处更改

7.存量是1000000,也可以在构造函数的totalSupply处更改

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/921770
推荐阅读
相关标签
  

闽ICP备14008679号