这段时间以来,以太坊通证很流行。这些通证可以用来代表现实世界的各种价值单位:黄金 、 谎言 、 猫咪 甚至是类似 公司股票 一样的东西。迄今为止,人们已经募集了 20 亿美元的通证 。那些通证是以 ERC20 为标准的,人们可以轻松地在钱包之间进行交易。在这篇教程中,我准备指导你部署你自己的 ERC20 通证到真实的以太坊网络上去。
事先准备:
一个文本编辑器(Atom 不错,不过我喜欢 Vim )
对命令行和终端(模拟器)有起码的了解。Mac 内置的应用“终端”就很好,不过我喜欢 iTerm2
Chrome 浏览器
Node.js 8 (或更高版本)
你的通证的名字。我的准备叫做 HamburgerCoin(汉堡币)
你需要做的第一件事是安装 MetaMask 。访问 Metamask 网站 并点击“Get Chrome Extention”。
Metamask 可以让你通过 Chrome 在以太坊上进行交易。它依靠运行着公开以太坊节点的 Infura ,所以你不用自己运行以太坊全节点。如果你颇具探索精神,你也可以下载和安装 Mist 以替代它。运行 Mist 就可以让你运行你自己的以太坊节点。运行自己的节点你就需要将你的计算机与该网络进行同步,这需要不短的时间。从技术上讲这更安全,因为这样你不必信任 Infura 来处理你的交易。Infura 可以忽略你的交易而干预你,但是它并不能偷走你的钱。因为安装 Metamask 比 Mist 更快也更简单,所以我假设你在下面的教程中使用 Metamask。
接着你需要安装 truffle :
1 2 $ npm install -g truffle
现在为你自己的新通证创建一个新目录,cd 到其中并初始化你的 truffle 项目。
1 2 3 4 $ mkdir hamburger-coin$ cd hamburger-coin$ truffle init
很好,你的 truffle 项目已经设置好了!
现在来创建我们的通证。首先我们需要安装 OpenZepplin 框架。OpenZepplin 框架包括了大量预先构建好的合约,包括我们要部署的 ERC20 通证合约。
(只需要按下回车接受默认值即可)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 $ npm init package name: (hamburger-coin)version: (1.0 .0 )description: entry point: (truffle.js) test command: git repository:keywords: author: license: (ISC) About to write to /Users/masonf/ src/hamburger-coin/ package.json:{ "name" : "hamburger-coin" , "version" : "1.0.0" , "description" : "" , "main" : "truffle.js" , "directories" : { "test" : "test" } , "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" } , "author" : "" , "license" : "ISC" } Is this ok? (yes) yes $ npm install zeppelin-solidity
现在我们可以创建我们的通证合约了。创建一个 contracts/HamburgerCoin.sol
文件并加入如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 pragma solidity ^0.4 .18 ;import "zeppelin-solidity/contracts/token/StandardToken.sol" ; contract HamburgerCoin is StandardToken { string public name = "HamburgerCoin" ; string public symbol = "HBC" ; uint public decimals = 2 ; uint public INITIAL_SUPPLY = 10000 * (10 ** decimals); function HamburgerCoin() public { totalSupply_ = INITIAL_SUPPLY; balances[msg.sender] = INITIAL_SUPPLY; } }
(LCTT 译注:上述合约内容中指定了合约的名称、符号和供应量。在 ERC20 当中,通证的供应量其实是整数,上述合约中通证的实际供应量是 10000 * 100 个,出于显示 2 位小数的需求,你在合约浏览器、钱包软件中看到和操作的 1 个通证,实际上在交易中是以 100 个进行的。)
OpenZepplin 的 StandardToken
是一个标准的 ERC20 通证。如果你感兴趣,你可以看看它的 源代码 以了解是如何工作的。
实际上并不太复杂。该合约有一个 地址到余额 的映射(LCTT 译注:你可以理解为哈希、关联数组),它也有一个 允许转账 的列表。你可以看做是支票。你可以写张支票,但是直到它被兑付前,钱并不会被转账。
如果有人要转走一些资金,你可以在合约上调用 approve 方法,设置你要发送的通证数量。这就像是写支票一样。
然后调用 transferFrom 会实际进行转账。
我们可以从头写这些合约,但是最好采用经过完备的社区测试的合约。从头写一个 ERC20 通证那就是另外一篇文章了。
试着运行 compile
来编译我们的合约:
1 2 3 4 5 6 7 8 9 10 11 $ truffle compile Compiling ./contracts/HamburgerCoin.sol... Compiling zeppelin-solidity/contracts/math/SafeMath.sol... Compiling zeppelin-solidity/contracts/ownership/Ownable.sol... Compiling zeppelin-solidity/contracts/token/BasicToken.sol... Compiling zeppelin-solidity/contracts/token/ERC20.sol... Compiling zeppelin-solidity/contracts/token/ERC20Basic.sol... Compiling zeppelin-solidity/contracts/token/MintableToken.sol... Compiling zeppelin-solidity/contracts/token/StandardToken.sol... Writing artifacts to ./build/contracts Next you'll need to add a migration file which will tell truffle how to deploy your contract.
接下来我们需要增加一个 truffle 迁移 。
创建 migrations/2_deploy_hamburgercoin.js
文件并添加如下内容:
1 2 3 4 5 6 var HamburgerCoin = artifacts.require("./HamburgerCoin.sol" ) module.exports = function(deployer) { deployer.deploy(HamburgerCoin) }
现在让我们配置 truffle 以能够使用 Infura 公共节点。如果我们要部署到公共节点,那就需要钱包的私钥。我们可以将该私钥包含在我们的源代码当中,但是如果任何人可以访问你的源代码(和版本库),他就能够偷走我们所有的汉堡币!要避免这种情况,我们会使用 dotenv node.js 模块。(LCTT 译注:dotenv 用于存储机密信息的文件 .env 是以 “.” 开头的,默认不会进入版本库,当然,如果有人能查看你全部的项目文件,你的私钥还是会被泄露。)
让我们安装部署到 Infura 所需的所有模块。
1 2 npm install --save -dev dotenv truffle-wallet-provider ethereumjs-wallet
(LCTT 译注:可能安装过程中会有很多警告,大多应该是属于定义了未使用的变量和方法的编译警告,可以忽略。)
现在编辑 truffle.js
并(原样)加入如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 require ('dotenv' ).config ();const Web3 = require ("web3" );const web3 = new Web3 ();const WalletProvider = require ("truffle-wallet-provider" );const Wallet = require ('ethereumjs-wallet' );var mainNetPrivateKey = Buffer.from (process.env["MAINNET_PRIVATE_KEY" ], "hex" )var mainNetWallet = Wallet.fromPrivateKey (mainNetPrivateKey);var mainNetProvider = new WalletProvider (mainNetWallet, "https://mainnet.infura.io/" );var ropstenPrivateKey = Buffer.from (process.env["ROPSTEN_PRIVATE_KEY" ], "hex" )var ropstenWallet = Wallet.fromPrivateKey (ropstenPrivateKey);var ropstenProvider = new WalletProvider (ropstenWallet, "https://ropsten.infura.io/" ); module.exports = { networks: { development: { host: "localhost" , port: 8545 , network_id: "*" }, ropsten: { provider: ropstenProvider, gas: 4600000 , gasPrice: web3.toWei ("20" , "gwei" ), network_id: "3" , }, mainnet: { provider: mainNetProvider, gas: 4600000 , gasPrice: web3.toWei ("20" , "gwei" ), network_id: "1" , } } };
(LCTT 译注:原文采用 new Buffer
来获取私钥设置,但 node.js 升级后,废弃了 new Buffer
这种用法,运行时会发出警告,所以上面我修改为使用 Buffer.from
。)
接下来我们从 Metamask 中得到我们的私钥:
点击你的 Chrome 窗口右上角的狐狸图标。
点击 “Account 1” 右侧的省略号。
点击 “Export Private Key”。
输入你的密码。
点击该文字以复制私钥到剪贴板。
然后打开 .env
文件,并像下面这样贴入你的私钥(对于 Ropsten 测试网和 Mainnet 主网,你的私钥是一样的):
1 2 3 ROPSTEN_PRIVATE_KEY ="123YourPrivateKeyHere" MAINNET_PRIVATE_KEY ="123YourPrivateKeyHere"
接下来,让我们部署到 Ropsten 以太坊测试网。
以太坊测试网是一个你可以测试合约的地方。此外还有 Kovan 和 Rinkeby 测试网。我在这个教程中选择 Ropsten 是因为现在很容易得到 Ropsten 的测试 ETH。这些测试网都类似,你可以使用任何一个你喜欢的,但是在此教程当中我假设你在使用 Ropsten。访问 https://faucet.metamask.io/ 以得到一些测试 ETH。从 faucet 得到一些 ETH 后,你就可以部署了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 $ truffle deploy --network ropsten Compiling ./contracts/HamburgerCoin.sol... Compiling ./contracts/Migrations.sol... Compiling zeppelin-solidity/contracts/math/SafeMath.sol... Compiling zeppelin-solidity/contracts/token/BasicToken.sol... Compiling zeppelin-solidity/contracts/token/ERC20.sol... Compiling zeppelin-solidity/contracts/token/ERC20Basic.sol... Compiling zeppelin-solidity/contracts/token/StandardToken.sol... Writing artifacts to ./build/contracts Using network 'ropsten'. Running migration: 1_initial_migration.js Deploying Migrations... ... 0xc2bbe6bf5a7c7c7312c43d65de4c18c51c4d620d5bf51481ea530411dcebc499 Migrations: 0xd827b6f93fcb50631edc4cf8e293159f0c056538 Saving successful migration to network... ... 0xe6f92402e6ca0b1d615a310751568219f66b9d78b80a37c6d92ca59af26cf475 Saving artifacts... Running migration: 2_deploy _contracts.js Deploying HamburgerCoin... ... 0x02c4d47526772dc524851fc2180b338a6b037500ab298fa2f405f01abdee21c4 HamburgerCoin: 0x973b1a5c753a2d5d3924dfb66028b975e7ccca51 Saving artifacts...
在 “Saving aritfacts” 上面的这行即是你的合约的新地址。
复制并黏贴该地址到 Ropsten Etherscan 搜索框 ,你就能看到你新部署的合约。
现在你可以在任何 ERC20 兼容的钱包,如 Mist 、MyEtherWallet (LCTT 译注:或 ImToken 这样的手机应用)里面使用你的通证了。
为了这篇教程,我构建了一个名为 Etherface 的钱包来做演示。
首先你需要添加你的通证到 Etherface:
访问 http://etherface.io/ 。
确认你在 Metamask 中选择了 “Ropsten” 网络。
点击 “Tokens”。
点击右上角的加号按钮。
输入上面的合约地址。
如果你有朋友想要一些汉堡币,你现在就可以发送给他们了。如果没有,你也可以在你的两个账号间测试转账:
在 Metamask 中点击 “切换账号”按钮(在右上角),并改变你的账号为 “Account 2”。
点击 “Account 2” 右边的省略号,然后选择 “Copy Address to clipboard”。
切换回 “Account 1”,这很重要!否则交易会失败。
在 Etherface 中你的余额下点击 “Send”。
黏贴 “Account 2” 的地址。
输入你要发送的数量。
Metamask 会弹出确认窗口,点击 “Submit”。
等大约 15-30 秒。
你的 “Account 1” 的余额应该会减少,“Account 2” 现在会有了一些汉堡币!
最后,让我们来部署到主网(LCTT 译注:这会花费你真实的 ETH,你可以通过查看前面部署到 Ropsten 的合约信息中了解花费了多少 gas,以相应估计实际要花费多少 ETH):
1 2 $ truffle deploy --network mainnet
你可以如前面一样加你的通证到 Etherface ,并发送你新打造的通证给你的朋友们了!