ERC20 解读

1.ERC20

什么叫做代币?

代币可以在以太坊中表示任何东西:

  • 在线平台中的信誉积分
  • 游戏中一个角色的技能
  • 彩票卷
  • 金融资产类似于公司股份的资产
  • 像美元一样的法定货币
  • 一盎司黄金
  • 及更多...

以太坊的这种强大特点必须以强有力的标准来处理,对吗? 这正是 ERC-20 发挥其作用的地方! 此标准允许开发者构建可与其他产品和服务互相操作的代币应用程序。

什么是 ERC-20?

ERC-20 提出了一个同质化代币的标准,换句话说,它们具有一种属性,使得每个代币都与另一个代币(在类型和价值上)完全相同。 例如,一个 ERC-20 代币就像以太币一样,意味着一个代币会并永远会与其他代币一样。

ERC-20(以太坊意见征求 20)由 Fabian Vogelsteller 提出于 2015 年 11 月。这是一个能实现智能合约中代币的应用程序接口标准。

ERC-20 的功能示例包括:

  • 将代币从一个帐户转到另一个帐户
  • 获取帐户的当前代币余额
  • 获取网络上可用代币的总供应量
  • 批准一个帐户中一定的代币金额由第三方帐户使用

如果智能合约实施了下列方法和事件,它可以被称为 ERC-20 代币合约,一旦部署,将负责跟踪以太坊上创建的代币。

上面是官方的说法, 代币嘛,比如游戏:我们用金钱充值,经过一定换算,人民币对应的换算游戏的货币。这些游戏货币就是代币。

当然,只是打个比方,代币更多还是区块链所属的概念。

当然简单的来讲:

ERC20是以太坊定义的一个合约接口规范,符合该规范的合约被称为以太坊代币。

1.这是以太坊官方给的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);

我们就围绕ERC20自己写个代币合约。

顺便在代码注释出讲解相应功能。

2.自己写一个ERC20合约实现

1.ERC20

pragma solidity  ^0.4.25;

interface ERC20 {
    // 返回代币名称
    function name()public view returns (string memory);    
    // 返回代币符号
    function symbol()public view returns (string memory);
    // 返回代币小数点后位数
    function decimals()public view returns (uint8);

    
    // 总代币数量
    function totalSupply()public view returns (uint256);
    // 返回 _owner 地址拥有的代币数量。
    function balanceOf(address _owner)public view returns (uint256 balance);
     // 将 value 数量的代币发送给 to 地址,返回布尔值告知是否执行成功。触发 Transfer 事件。
    function transfer(address _to, uint256 _value)public returns (bool success);
    // 将 value 数量的代币从 from 地址发送到 to 地址,返回布尔值告知是否执行成功。触发 Transfer 事件。
    function transferFrom(address _from, address _to, uint256 _value)public returns (bool success);
    // 授权 spender 可以花费  value 数量的代币,返回布尔值告知是否执行成功。触发 Approval 事件。
    function approve(address _spender, uint256 _value)public returns (bool success);
    // 返回授权花费者 spender 通过 transferFrom 代表所有者花费的剩余代币数量。
    // 默认情况下为零。当 approve 和 transferFrom 被调用时,值将改变。
    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);

}   

2. Jzm20

contract Jzm20 is ERC20 {

    ///
     Filed
    ///
    uint256 private _totalSupply;
    string private _symbol;

     // 地址余额
    mapping(address => uint256) private _balances;
     // 授权地址余额
    mapping(address => mapping(address => uint256)) private _allowances;
    


    ///
     Function
    ///
    constructor (string  symbol_) public {
        _symbol = symbol_;
    }
    function name() public view returns (string memory) {
        return "Jzm20";
    }   
    function symbol() public view returns (string memory){
        return _symbol;
    }
    function decimals() public view returns (uint8){
        return 18;
    }

    function totalSupply() public view returns (uint256){
        return _totalSupply;
    }
    function balanceOf(address _owner) public view returns (uint256 balance){
        balance =  _balances[_owner];
    }

    // 给指定owner地址创建value数量代币
    function mint(address _owner,uint256 _value) public {
        require(_owner != address(0),"Jzm20: owner address is not empty");
        _balances[_owner] = _value;
        _totalSupply = _sum(_totalSupply,_value);
        emit Transfer(address(0),_owner,_value);
    }

    function transfer(address _to, uint256 _value) public returns (bool success){
        address owner = msg.sender;
        _transfer(owner,_to,_value);
        success = true;
    }

    function transferTo(address _from, address _to, uint256 _value) public returns(bool success) {
        _transfer(_from,_to,_value);
        success = true;
    }

    // 这个是给spender权限者使用的
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
        address spender = msg.sender;
        uint256 approveBalance = allowance(_from,spender);

        _allowances[_from][spender] = _sub( _allowances[_from][spender],_value); // 相应地授权金额回增加
        require(approveBalance >= _value,"Jzm20:approve balance is Insufficient balance transfer");
        _transfer(_from,_to,_value);
        success = true;
    }

    function approve(address _spender, uint256 _value) public returns (bool success){
        address owner = msg.sender;
        require(_balances[owner] >= _value,"Jzm20:owner balance is not enough to value memory!");
        _allowances[msg.sender][_spender] = _sum( _allowances[msg.sender][_spender],_value);
        emit Approval(owner,_spender,_value);
        success = true;
    }   
    
    function allowance(address _owner, address _spender) public view returns (uint256 remaining){
        remaining = _allowances[_owner][_spender];
    }

    function _sum(uint256 a,uint256 b) private pure returns(uint256) {
        uint256  c = a + b;
        require(c >= a && c >= b,"Jm20:An arithmetic overflow has occurred");
        return c;
    }

    function _sub(uint256 a,uint256 b) private  pure returns(uint256) {
        uint256 c = a - b;
        require(c <= a,"Jm20:An arithmetic overflow Under has occurred");
        return c;
    }

    function _transfer( address _from, address _to, uint256 _value) private {
        require(_balances[_from] >= _value,"Jm20:owner balance is Insufficient balance transfer");
        require(_to != address(0),"Jm20:to can not be empty address!");

        _balances[_to] = _sum(_balances[_to],_value); 
        _balances[_from] = _sub(_balances[_from],_value);
        emit Transfer(_from,_to,_value);
    }
}

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

本郡主是喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值