以太坊研究系列【代币发行】

Words
793
Reading
4 min
9y
Listen to this post
~5 min

此文档为个人整理学习使用,部分内容来源于网络,也期待能给你带来益处。

以太坊代币

以太坊生态系统中的代币可以代表任何可以交易的东西:币(coin)、积分、黄金证券、欠条(IOU)等。
因为所有的代币都以标准化的方式实现一些基本的特性,这样意味着你自己创建的代币将于以太坊钱包、使用相同标准的任何其它客户端或者合约相兼容。

网上代币合约

启动私链,在mist钱包中新建合约,把以下代码拷到合约窗口中,不同版本可能会有一些错误,自己简单改一下:

pragma solidity ^0.4.18;

contract MyToken {
    /* Public variables of the token */
    string public name;
    string public symbol;
    uint8 public decimals;

/* This creates an array with all balances */
mapping (address => uint256) public balanceOf;

/* This generates a public event on the blockchain that will notify clients */
event Transfer(address indexed from, address indexed to, uint256 value);

/* Initializes contract with initial supply tokens to the creator of the contract */
function MyToken(uint256 _supply, string _name, string _symbol, uint8 _decimals) public{
    /* if supply not given then generate 1 million of the smallest unit of the token */
    if (_supply == 0) _supply = 1000000;

    /* Unless you add other functions these variables will never change */
    balanceOf[msg.sender] = _supply;
    name = _name;
    symbol = _symbol;

    /* If you want a divisible token then add the amount of decimals the base unit has  */
    decimals = _decimals;
}

/* Send coins */
function transfer(address _to, uint256 _value) private {
    /* if the sender doenst have enough balance then stop */
    if (balanceOf[msg.sender] < _value) return;
    if (balanceOf[_to] + _value < balanceOf[_to]) return;

    /* Add and subtract new balances */
    balanceOf[msg.sender] -= _value;
    balanceOf[_to] += _value;

    /* Notifiy anyone listening that this transfer took place */
    Transfer(msg.sender, _to, _value);
}

}

显示如下
title

在右边选择部署的合约为“MyToken”,右边更改系数定制自己的货币。
supply: 货币总量,name: 货币名字,symbol:货币符号,decimals:货币单位精确到小数点后几位。

如下图发行一个VIP标志,总数量为100个。
title

点击发布,输入密码确定等一会矿工确认后在“最新交易”中可以看到
title

点击“定制化合约”中刚创建的MyToken合约,选择右边的“复制地址”,这个地址在查看代币中要用到。

点击“定制化TOKEN”中的“查看代币”,粘贴地址到TOKEN地址,确定
title

这样就能看到刚创建的100个VIP标志的代币了!
title

发送新创建的代币

点击左上角的“发送”,进入后选择刚才创建的帐号,因为现在只有这个帐号有代币,选择其它帐号看不到代币,只有ETHER,这个帐号下就有两种货币:ETHER和VF
title

例如我现在要给account2发送1个标志,把account2的地址“0x469f07278600b1cb031448fd25f187f24a89ecb6”粘贴到“发送至”输入框,数量为1,发送即可

不过我这私链上有问题,出现错误:

[2018-01-12T18:40:59.931] [ERROR] ipcProviderBackend - Send request failed { code: -32000,
  message: 'gas required exceeds allowance or always failing transaction' }

mist代币合约

其实mist钱包“定制化TOKEN”内就有两个链接说明如何创建代币的,如下:
https://ethereum.org/token#the-code
https://www.ethereum.org/token

那就找一个比较完整的代币代码直接粘贴过来吧

pragma solidity ^0.4.16;

interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; }

contract TokenERC20 {
    // Public variables of the token
    string public name;
    string public symbol;
    uint8 public decimals = 18;
    // 18 decimals is the strongly suggested default, avoid changing it
    uint256 public totalSupply;

// This creates an array with all balances
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;

// This generates a public event on the blockchain that will notify clients
event Transfer(address indexed from, address indexed to, uint256 value);

// This notifies clients about the amount burnt
event Burn(address indexed from, uint256 value);

/**
 * Constrctor function
 *
 * Initializes contract with initial supply tokens to the creator of the contract
 */
function TokenERC20(
    uint256 initialSupply,
    string tokenName,
    string tokenSymbol
) public {
    totalSupply = initialSupply * 10 ** uint256(decimals);  // Update total supply with the decimal amount
    balanceOf[msg.sender] = totalSupply;                // Give the creator all initial tokens
    name = tokenName;                                   // Set the name for display purposes
    symbol = tokenSymbol;                               // Set the symbol for display purposes
}

/**
 * Internal transfer, only can be called by this contract
 */
function _transfer(address _from, address _to, uint _value) internal {
    // Prevent transfer to 0x0 address. Use burn() instead
    require(_to != 0x0);
    // Check if the sender has enough
    require(balanceOf[_from] >= _value);
    // Check for overflows
    require(balanceOf[_to] + _value > balanceOf[_to]);
    // Save this for an assertion in the future
    uint previousBalances = balanceOf[_from] + balanceOf[_to];
    // Subtract from the sender
    balanceOf[_from] -= _value;
    // Add the same to the recipient
    balanceOf[_to] += _value;
    Transfer(_from, _to, _value);
    // Asserts are used to use static analysis to find bugs in your code. They should never fail
    assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
}

/**
 * Transfer tokens
 *
 * Send `_value` tokens to `_to` from your account
 *
 * @param _to The address of the recipient
 * @param _value the amount to send
 */
function transfer(address _to, uint256 _value) public {
    _transfer(msg.sender, _to, _value);
}

/**
 * Transfer tokens from other address
 *
 * Send `_value` tokens to `_to` on behalf of `_from`
 *
 * @param _from The address of the sender
 * @param _to The address of the recipient
 * @param _value the amount to send
 */
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
    require(_value <= allowance[_from][msg.sender]);     // Check allowance
    allowance[_from][msg.sender] -= _value;
    _transfer(_from, _to, _value);
    return true;
}

/**
 * Set allowance for other address
 *
 * Allows `_spender` to spend no more than `_value` tokens on your behalf
 *
 * @param _spender The address authorized to spend
 * @param _value the max amount they can spend
 */
function approve(address _spender, uint256 _value) public
    returns (bool success) {
    allowance[msg.sender][_spender] = _value;
    return true;
}

/**
 * Set allowance for other address and notify
 *
 * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
 *
 * @param _spender The address authorized to spend
 * @param _value the max amount they can spend
 * @param _extraData some extra information to send to the approved contract
 */
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
    public
    returns (bool success) {
    tokenRecipient spender = tokenRecipient(_spender);
    if (approve(_spender, _value)) {
        spender.receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }
}

/**
 * Destroy tokens
 *
 * Remove `_value` tokens from the system irreversibly
 *
 * @param _value the amount of money to burn
 */
function burn(uint256 _value) public returns (bool success) {
    require(balanceOf[msg.sender] >= _value);   // Check if the sender has enough
    balanceOf[msg.sender] -= _value;            // Subtract from the sender
    totalSupply -= _value;                      // Updates totalSupply
    Burn(msg.sender, _value);
    return true;
}

/**
 * Destroy tokens from other account
 *
 * Remove `_value` tokens from the system irreversibly on behalf of `_from`.
 *
 * @param _from the address of the sender
 * @param _value the amount of money to burn
 */
function burnFrom(address _from, uint256 _value) public returns (bool success) {
    require(balanceOf[_from] >= _value);                // Check if the targeted balance is enough
    require(_value <= allowance[_from][msg.sender]);    // Check allowance
    balanceOf[_from] -= _value;                         // Subtract from the targeted balance
    allowance[_from][msg.sender] -= _value;             // Subtract from the sender's allowance
    totalSupply -= _value;                              // Update totalSupply
    Burn(_from, _value);
    return true;
}

}

这次把这个代币叫做和SuperVipFlag,如下
title

用这个代码都不用去“定制化TOKEN”的“查看代币”手动添加了,合约创建完就可以看到代币了,但是缺省是18位小数,实际这个标志是不可分割的。

title

而且这次发送SVF也不提示出错了,成功完成代币转移!
在用户钱包中也可以查看到代币的数量,不过这个mist版本显示有点问题,小数点为什么用“,”呢?!

title

更完整例子

https://www.ethereum.org/token

参考

http://ethfans.org/topics/118

***************************************

作者简介


老鱼,从事互联网技术十余年,知名上市公司CTO;炒股十余年,从亏损几十万到略有盈利;顺应创业大潮多次创业,在传统行业和手游行业有所获;研习佛学易理,性格淡泊清净!

欢迎有兴趣的朋友加入微信群和电报群,一起学习探讨,一起实现咱们的小目标!

  • 百分百区块链群,微信扫码后会再显示一个二维码,长按图片“识别图中二维码”加入!


以太坊研究系列【代币发行】 | Ecency