首先先来了解一下什么是ERC20协议

ERC20的全名叫:Ethereum Request for Comments 20,最初作为一种尝试,旨在为以太坊(Ethereum)上的token合约提供一个特征与接口的共同标准。ERC-20有很多好处,不仅兼容很多的token,还包括允许钱包显示数以百计不同token的账户余额;创建一个交易工具,只需提供token合约的地址就可以将更多token列入表中。

简单来说,任何ERC-20代币都能立即兼容以太坊钱包(几乎所有支持以太币的钱包,包括JaxxMEWimToken等,也支持erc-20的代币)。

本质上来说,一个token合约就是一个包含了一个对账户地址及其余额的映射的智能合约(Smart Contract)。账户余额表示一种由合约创建者定义的值:一个token合约也许使用余额来表示物理对象,或是表示另一种货币价值,还可以表示持有人的名誉。余额的单位通常被称为token。

ERC20是各个代币的标准接口。ERC20 代币仅仅是以太坊代币的子集,为了充分兼容 ERC20,开发者需要将一组特定的函数(接口)集成到他们的智能合约中,以便在高层面能够执行这些操作:获得代币总供应量、获得账户余额、转让代币、批准花费代币。

ERC20 让以太坊区块链上的其他智能合约和去中心化应用之间无缝交互。一些具有部分但非所有ERC20标准功能的代币被认为是部分ERC20兼容,这还要视其具体缺失的功能而定,但总体是它们仍然很容易与外部交互。

为什么要基于ERC20发行加密货币呢

ERC20是一段代码,主要有6个功能,分别是名称,简写,以及可以支持的最大位数以及定义查询方法等等。从ERC20发币的开源代码可以看出,如果一旦你要发行加密货币,首先就是要确定名称,代币简称,总量,代币精确小数点后多少位等等。

ERC20协议作为当今最广泛使用的协议,仅2019一年,光在etherscan网站上显示符合ERC20设计标准的加密货币种类就已经超过了360w种。

好,那么现在开始:

正文

开始前请准备以下文件:

  • 一个可以连接全世界的网络
  • MetaMask 浏览器插件(自行前往插件中心下载安装)

创建智能合约

首先,一个标准ERC20协议的智能合约是必须的:

代码①:EIP20.sol

pragma solidity ^0.4.21;

import "./EIP20Interface.sol";


contract EIP20 is EIP20Interface {

    uint256 constant private MAX_UINT256 = 2**256 - 1;
    mapping (address => uint256) public balances;
    mapping (address => mapping (address => uint256)) public allowed;
    /*
    NOTE:
    The following variables are OPTIONAL vanities. One does not have to include them.
    They allow one to customise the token contract & in no way influences the core functionality.
    Some wallets/interfaces might not even bother to look at this information.
    */
    string public name;                   //fancy name: eg Simon Bucks
    uint8 public decimals;                //How many decimals to show.
    string public symbol;                 //An identifier: eg SBX

    function EIP20(
        uint256 _initialAmount,
        string _tokenName,
        uint8 _decimalUnits,
        string _tokenSymbol
    ) public {
        balances[msg.sender] = _initialAmount;               // Give the creator all initial tokens
        totalSupply = _initialAmount;                        // Update total supply
        name = _tokenName;                                   // Set the name for display purposes
        decimals = _decimalUnits;                            // Amount of decimals for display purposes
        symbol = _tokenSymbol;                               // Set the symbol for display purposes
    }

    function transfer(address _to, uint256 _value) public returns (bool success) {
        require(balances[msg.sender] >= _value);
        balances[msg.sender] -= _value;
        balances[_to] += _value;
        emit Transfer(msg.sender, _to, _value); //solhint-disable-line indent, no-unused-vars
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        uint256 allowance = allowed[_from][msg.sender];
        require(balances[_from] >= _value && allowance >= _value);
        balances[_to] += _value;
        balances[_from] -= _value;
        if (allowance < MAX_UINT256) {
            allowed[_from][msg.sender] -= _value;
        }
        emit Transfer(_from, _to, _value); //solhint-disable-line indent, no-unused-vars
        return true;
    }

    function balanceOf(address _owner) public view returns (uint256 balance) {
        return balances[_owner];
    }

    function approve(address _spender, uint256 _value) public returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value); //solhint-disable-line indent, no-unused-vars
        return true;
    }

    function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }
}

代码②:EIP20Interface.sol

pragma solidity ^0.4.21;
contract EIP20Interface {
    /* This is a slight change to the ERC20 base standard.
    function totalSupply() constant returns (uint256 supply);
    is replaced with:
    uint256 public totalSupply;
    This automatically creates a getter function for the totalSupply.
    This is moved to the base contract since public getter functions are not
    currently recognised as an implementation of the matching abstract
    function by the compiler.
    */
    /// total amount of tokens
    uint256 public totalSupply;

    /// @param _owner The address from which the balance will be retrieved
    /// @return The balance
    function balanceOf(address _owner) public view returns (uint256 balance);

    /// @notice send `_value` token to `_to` from `msg.sender`
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return Whether the transfer was successful or not
    function transfer(address _to, uint256 _value) public returns (bool success);

    /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
    /// @param _from The address of the sender
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return Whether the transfer was successful or not
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);

    /// @notice `msg.sender` approves `_spender` to spend `_value` tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @param _value The amount of tokens to be approved for transfer
    /// @return Whether the approval was successful or not
    function approve(address _spender, uint256 _value) public returns (bool success);

    /// @param _owner The address of the account owning tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @return Amount of remaining tokens allowed to spent
    function allowance(address _owner, address _spender) public view returns (uint256 remaining);

    // solhint-disable-next-line no-simple-event-func-name
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

看不懂代码没关系,你需要做的就是复制一下,前往Remix(官方在线的Solidity编译器),什么你看到英文?没关系,贴心准备了中文版Remix(虽然是第三方的,但效果一样,比较这玩意已经开源了)。

看图操作,代码①文件名随意,代码②必须为 EIP20Interface.sol

点击"+",拷贝现有的ERC20智能合约,将EIP20.solEIP20Interface.sol复制到remix中。

生成代币

切换到Run,注意环境选择injected web3,选择需要运行的合约“ZML”,在Deploy中,输入参数。如下图

  • 第一个参数是Token的数量;
  • 第二个参数是Token的全称;
  • 第三个参数是Token的精度,即令牌最小为小数点后几位;
  • 第四个参数是Token的符号;

    例如:10000,“ZML Token”,2,“ZML”。

填写完成后,点击“Deploy”后会弹出合约确认界面,直接点击submit,等待合约确认。

当合约执行完毕后,可以在 MetaMask 中看到一条新的记录,点击确认。

耐心等待智能合约的创建,大概几分钟。

TO 一栏显示的 0x446897451201bDcC1023d3C954788c9517F46FDf 即为刚刚创建的加密货币合约地址。

添加Token

从上图红色框中,拷贝智能合约地址。填入到"Token Contract Address(代币联系人地址)"中,然后系统会自动填充"Token Symbol(代币符号)"和“Decimals of precision(精确小数点)”,点击下一步。

现在,前往区块链浏览器就可以看到你发行的代币啦

什么,嫌麻烦。。。好吧。。。点击前往》》https://tools.94eth.com/ 看图,小白式操作。