博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
以太坊·代币开发详解
阅读量:6159 次
发布时间:2019-06-21

本文共 8998 字,大约阅读时间需要 29 分钟。

hot3.png

以太坊·代币开发详解

本文节选自《Netkiller Blockchain 手札》

Netkiller Blockchain 手札

本文作者最近在找工作,有意向致电 13113668890

Mr. Neo Chan, 陈景峯(BG7NYT)

中国广东省深圳市龙华新区民治街道溪山美地 518131 +86 13113668890 <netkiller@msn.com>

文档始创于2018-02-10

版权 © 2018 Netkiller(Neo Chan). All rights reserved.

版权声明

转载请与作者联系,转载时请务必标明文章原始出处和作者信息及本声明。

 

 

http://www.netkiller.cnhttp://netkiller.github.iohttp://netkiller.sourceforge.net

http://www.netkiller.cn

http://netkiller.github.io

http://netkiller.sourceforge.net

 

 

微信订阅号 netkiller-ebook (微信扫描二维码)QQ:13721218 请注明“读者”QQ群:128659835 请注明“读者”

微信订阅号 netkiller-ebook (微信扫描二维码)

QQ:13721218 请注明“读者”

QQ群:128659835 请注明“读者”

 

http://www.netkiller.cn

http://netkiller.github.io

http://netkiller.sourceforge.net

 

微信订阅号 netkiller-ebook (微信扫描二维码)

QQ:13721218 请注明“读者”

QQ群:128659835 请注明“读者”

$Data$

内容摘要

这一部关于区块链开发及运维的电子书。

为什么会写区块链电子书?因为2018年是区块链年。

这本电子书是否会出版(纸质图书)? 不会,因为互联网技术更迭太快,纸质书籍的内容无法实时更新,一本书动辄百元,很快就成为垃圾,你会发现目前市面的上区块链书籍至少是一年前写的,内容已经过时,很多例子无法正确运行。所以我不会出版,电子书的内容会追逐技术发展,及时跟进软件版本的升级,做到内容最新,至少是主流。

这本电子书与其他区块链书籍有什么不同?市面上大部分区块链书籍都是用2/3去讲区块链原理,只要不到 1/3 的干货,干货不够理论来凑,通篇将理论或是大谈特谈区块链行业,这些内容更多是头脑风暴,展望区块链,均无法落地实施。本书与那些书籍完全不同,不讲理论和原理,面向应用落地,注重例子,均是干货。

电子书更新频率?每天都会有新内容加入,更新频率最迟不会超过一周,更新内容请关注 https://github.com/netkiller/netkiller.github.io/commits/master

本文采用碎片化写作,原文会不定期更新,请尽量阅读原文。

http://www.netkiller.cn/blockchain/index.html

9.4. 创建代币

https://ethereum.org/token

9.4.1. 合约文件

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;    }}

9.4.2. 部署合约

启动 Ethereum Wallet,点击 CONTRACTS 按钮,进入合约管理界面

 

23192021_wbER.png

点击 DEPLOY NEW CONTRACT 按钮,部署一个新合约

23192021_5yti.png

复制粘贴合约文件到 SOLIDITY CONTRACT SOURCE CODE 下方

SELECT CONTRACT TO DEPLOY 列表选择 “Token ERC 20”

Initial supply 是初始发行货币量

Token name 是代币名称

Token symbol 是代币符号

 

23192021_3uIc.png

拉动滚动调,找到下方 “DEPLOY”按钮,点击该按钮。

 

23192022_ly2c.png

输入账号密码,并点击“SEND TRANSACTION” 按钮。

 

23192022_SJGV.png

ERC20代币创建完成

9.4.3. 代币转账

进入钱包可以看到当前账号的以太币数量,在下方还能看到 ERC20 代币。

 

23192022_8wsm.png

点击 SEND 按钮

 

23192022_vBQe.png

填写 TO 地址 和 代币 500 个,点击 SEND 按钮

 

23192023_0kum.png

进入目标账号查看余额。

 

23192023_Kc2l.png

至此我们完成了,代币合约部署,实现了账号对账号的转账。下面我们来讲述如何开发。

以太币开发是指,使用程序实现代币的转账,因为我们不可能使用钱包手工转账。让代币落地就需要在程序中完成。

通常程序部署在WEB服务器,例如这样的场景,用户在网站上注册开户,赠送一定量的代币奖励。

这时我们就需要使用WEB3.js(Node) 或者WEB3J (Java API )完成网站或者手机APP访问以太坊,完成代币转账。

 

6.10.4. ERC20 Example

通过Web3操作代币转账

fs = require('fs');const Web3 = require('web3');const web3 = new Web3('http://localhost:8545');web3.versionconst abi = fs.readFileSync('netkiller/TokenERC20.abi', 'utf-8');const contractAddress = "0x05A97632C197a0496bc939C4e666c2E03Cb95DD4";const toAddress = "0x2C687bfF93677D69bd20808a36E4BC2999B4767C";var coinbase;web3.eth.getCoinbase().then(function (address){  coinbase = address;  console.log(address);});const contract = new web3.eth.Contract(JSON.parse(abi), contractAddress, { from: coinbase , gas: 100000});contract.methods.balanceOf('0x5c18a33DF2cc41a1bedDC91133b8422e89f041B7').call().then(console.log).catch(console.error);contract.methods.balanceOf('0x2C687bfF93677D69bd20808a36E4BC2999B4767C').call().then(console.log).catch(console.error);web3.eth.personal.unlockAccount(coinbase, "Netkiller").then(console.log);contract.methods.transfer('0x2C687bfF93677D69bd20808a36E4BC2999B4767C', 100).send().then(console.log).catch(console.error);contract.methods.balanceOf('0x2C687bfF93677D69bd20808a36E4BC2999B4767C').call().then(console.log).catch(console.error);

上面的代码可是纯干货,你在网上看到最多的例子就是钱包完成合约,没有人提供web3代码完成同样的操作。我也翻遍了了网上找不到资料,这是我辛苦琢磨出来的,有不明白之处去我的QQ群里讨论把。

以上例子均使用最新版本

geth 1.8.1

web3.js 1.0.0-beta30

solc Version: 0.4.20

如果上面资料对你有用,打赏地址:http://www.netkiller.cn/home/donations.html

转载于:https://my.oschina.net/neochen/blog/1623585

你可能感兴趣的文章
Linux磁盘分区与挂载
查看>>
J2se学习笔记一
查看>>
DNS视图及日志系统
查看>>
老李分享:Android性能优化之内存泄漏 3
查看>>
mysql命令
查看>>
来自极客标签10款最新设计素材-系列七
查看>>
极客技术专题【009期】:web技术开发小技巧
查看>>
PHP 简单计算器代码实现
查看>>
正则表达式的知识普及
查看>>
docker使用笔记
查看>>
华为eNSP模拟器上实现FTP服务
查看>>
【全球AI人才排行榜】美国第一,中国仅排名第7
查看>>
微信小程序输入框input
查看>>
MySql字符串函数使用技巧
查看>>
Doc2Vec,Word2Vec文本相似度 初体验。
查看>>
系统ghost后变成一个盘了别的分区的文件怎么找回
查看>>
Win7+Ubuntu11
查看>>
请问华为三层交换机里面的那个从IP是个什么意思? -
查看>>
kFeedback开源啦
查看>>
大数据传输,文件传输的专业解决方案!
查看>>