ERC20-创建属于自己的虚拟货币

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处更改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值