当前位置:   article > 正文

ERC20(发币)

erc20

基本介绍

ERC 旨在建立使应用程序和合约更容易相互交互的约定

ETH(以太坊的原生加密货币)不同,ERC-20 代币不由账户持有代币只存在于合约中,就像一个自包含的数据库。它指定代币的规则(即名称、符号、可分割性)并保存一个将用户余额映射到他们的以太坊地址的列表。要移动代币,用户必须向合约发送交易,要求其将部分余额分配到其他地方。

当用户A调用转账函数,转给B部分金额时,这个调用会包含在一个看似常规的以太坊交易中,该交易向代币合约支付 0 ETH(交易的value为0)。该调用包含在交易的一个附加字段中,该字段指定 A想要做什么——在我们的例子中是将代币转移给 B,字段为Tokens Transferred。

注意:不要理解成当A调用转账函数,转的是A自身的以太币!只是代币!!
后续或许可以用代币来换取以太币

在这里插入图片描述

代币标准的目的

代币是以太坊这类通用编程区块链之上最显著和有用的应用形态。

  • 代币标准(ERC20、ERC721)是实现的最小单元
  • 使用代币标准,可完成合约之间的互操作性(多个合约去实现ERC20)
  • 安全

ERC20代币标准

最小单元

6个函数、2个事件

// 获取系统金额发行量
function totalSupply() virtual public view returns (uint totalSupply);
// 获取_owner余额
function balanceOf(address _owner) virtual public view returns (uint balance);
// 调用者(msg.sender)向 _t0 转账 _value
function transfer(address _to, uint256 _value) virtual public returns (bool success);
// 下面两个函数通常一起使用
// 2、授权后,被授权的人调用此函数,相当于手动取钱! 与transfer的区别在于 一个是甲方直接给你钱,一个是甲方授权,乙方自己取钱。
function transferFrom(address _from, address _to, uint256 _value) virtual public returns (bool success);
// 1、用于授权,msg.sender 授权给 _spender 可以动用 _value
function approve(address _spender, uint256 _value) virtual public returns (bool success);
// 查看_owner 授权给 _spender 的余额数量
function allowance(address _owner, address _spender) virtual public view returns (uint remaining);

// 转账事件,每次发生转账交易后触发事件让别人知道
event Transfer(address indexed _from, address indexed _to, uint256 _value);
// 授权事件,每次发生一个地址给另一个地址授权后触发事件让别人知道
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

可选单元

代币的名称

function name() virtual public view returns (string calldata);
  • 1

代币的代号、标识,通常为字母缩写

function symbol() virtual public view returns (string calldata);
  • 1

返回令牌使用的小数位数 - 例如"8",意味着将令牌量除以"100000000"以获取其用户的表示形式。

function decimals() virtual public view returns (uint8);
  • 1

solidity 0.6.0版本以后的不同点

1、合约contract 关键字之前需要加上abstract修饰

2、在抽象的函数内,添加virtual关键字

3、在继承函数时,需要对继承的函数名中加上override修饰符

在这里插入图片描述
在这里插入图片描述

实战代码展示(发币)

ERC20.sol合约:

pragma solidity ^0.6.0;

abstract contract ERC20 {
    // function name() public view returns (string)
    // function symbol() public view returns (string)
    // function decimals() public view returns (uint8)
    function totalSupply() virtual public view returns (uint totalSupply);
    function balanceOf(address _owner) virtual public view returns (uint balance);
    function transfer(address _to, uint256 _value) virtual public returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) virtual public returns (bool success);
    function approve(address _spender, uint256 _value) virtual public returns (bool success);
    function allowance(address _owner, address _spender) virtual public view returns (uint remaining);

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

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

pcCoin.sol合约 继承自 ERC20

pragma solidity ^0.6.0;

import "./ERC20.sol";

contract pcCoin is ERC20{
    uint256 _totalSupply; // 总供应量
    address public  _owner; // 部署合约的人
    uint8 public decimals = 18;  // 18 是建议的默认值
    mapping(address=>uint256) _balances; // address的余额
    mapping(address=>mapping(address=>uint256)) _approves; // a授权给b多少余额


    // 转账事件,转过之后让人能看到
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    // 授权事件,授权之后让人能看到
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    constructor(uint256 totalSupply) public {
        _owner = msg.sender; // _owner初始化为部署合约的人
        _totalSupply = totalSupply * 10 ** uint256(decimals);
        _balances[msg.sender] = _totalSupply;
    }

    // 设置权限
    modifier onlyOwner(){
        require(msg.sender == _owner);
        _;
    }

    //给指定账户投钱,只有部署合约的人有这个权限
    function airDrop(address _to, uint256 _value) onlyOwner public {
        require(_to != address(0) && _value > 0);
        _balances[_to] = _value;
        _totalSupply += _value; // 投过钱后,总供应量增加
    }

    // 返回总供应量
    function totalSupply() override public view returns(uint totalSupply){
        totalSupply = _totalSupply;
        return totalSupply;
    }

    function balanceOf(address _owner) override public view returns(uint balance){
        require(_owner != address(0), "owner should not be empty! ");
        return _balances[_owner];
    }

    function transfer(address _to, uint256 _value) override public returns (bool success){
        require(_to != address(0), "_to should not be empty !");
        require(_balances[msg.sender] >= _value && _value>0, "value should be valid !!");
        _balances[msg.sender] -= _value;
        _balances[_to] += _value;
        success = true;
        emit Transfer(msg.sender, _to, _value);
        return success;
    }

    // 被授权者来调用此函数,可理解为自己取钱,_from是授权的人
    function transferFrom(address _from, address _to, uint256 _value) override public returns (bool success){
        require(_from != address(0) && _to != address(0));
        require(_approves[_from][msg.sender] >= _value); // _from 授权给 msg.sender 的钱必须大于 _value
        _approves[_from][msg.sender] -= _value; // 取了钱后,_from 授权给 msg.sender 的钱就要减少
        _balances[_to] += _value;
        success = true;
        emit Transfer(_from, _to, _value);
        return success;
    }

    // 调用此函数,意为调用者(msg.sender)授权给_spender多少可动的钱
    function approve(address _spender, uint256 _value) override public returns (bool success){
        require(_spender != address(0));
        require(_balances[msg.sender] >= _value && _value > 0);
        _approves[msg.sender][_spender] += _value; // 授权
        _balances[msg.sender] -= _value; 
        success = true;
        emit Approval(msg.sender, _spender, _value);
        return success;
    }

    function allowance(address _owner, address _spender) override public view returns (uint remaining){
        return _approves[_owner][_spender];
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

部署到区块链网络(我部署的是ropsten测试网络)

在这里插入图片描述

下面可以调函数

在这里插入图片描述

过一会,支付一些燃油费之后,就部署到ropsten测试网络了。此时
在这里插入图片描述

在这里插入图片描述
添加后自己的代币计算发布成功了!可以给别的地址转币

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

闽ICP备14008679号