以太坊·代币开发详解


声明:本文转载自https://my.oschina.net/neochen/blog/1623585,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

以太坊·代币开发详解

本文节选自《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 按钮,进入合约管理界面

 

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

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

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

Initial supply 是初始发行货币量

Token name 是代币名称

Token symbol 是代币符号

 

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

 

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

 

ERC20代币创建完成

9.4.3. 代币转账

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

 

点击 SEND 按钮

 

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

 

进入目标账号查看余额。

 

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

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

通常程序部署在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.version const 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

本文发表于2018年02月25日 10:31
(c)注:本文转载自https://my.oschina.net/neochen/blog/1623585,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1663 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1