在本系列关于使用以太坊构建DApps教程的第2部分,咱们编写了TNS代币的代码。但咱们还没有编译,部署,测试或验证它。让咱们在这一部分作这些工做,以便咱们为下一步作好准备。php
此时咱们有一个包含一些Solidity代码的文件。但为了使以太坊虚拟机可以理解它,咱们须要将其转化为机器代码。另外,为了从Web应用程序与它进行通讯,咱们须要一个ABI(应用程序二进制接口),它是对某个智能合约中存在的函数的通用可读描述——不管是代币仍是更复杂的东西。咱们可使用Truffle的编译器当即为EVM和ABI建立机器代码。java
在项目文件夹中,运行:node
truffle compile
此命令将查看contracts
子文件夹内部,将它们所有编译并将其编译后的版本放入build
子文件夹中。请注意,若是你使用了上一部分的替代开发流程,那么咱们的TNSToken合约继承功能的全部父合约也将在其本身的文件中逐个编译。python
随意检查生成的JSON文件的内容。咱们的TNSToken应该有超过10000行的JSON代码。android
如今让咱们看看是否能够将它部署到咱们的仿真模拟器Ganache区块链中。若是Ganache还没有在终端的选项卡中或操做系统的应用程序中运行,请运行如下命令:git
ganache-cli
或运行应用程序以得到这样的屏幕:程序员
而后,回到咱们刚刚编译合约的文件夹中,咱们必须添加一个migration迁移。建立文件migrations/2_deploy_tnstoken.js
。若是你不熟悉Truffle生态系统中的迁移,请参阅本指南。web
咱们将如下内容放入该文件中:mongodb
var Migrations = artifacts.require("./Migrations.sol"); var TNSToken = artifacts.require("./TNSToken.sol"); module.exports = function(deployer, network, accounts) { deployer.deploy(TNSToken, {from: accounts[0]}); };
首先,经过请求Migrations.sol
进行完整的导入。每次迁移都须要这样作。接下来,部署代币意味着咱们须要导入其Solidity代码,咱们经过TNSToken.sol
(咱们在前一部分中编写的代码)来完成此操做。最后,只是迁移function(deployer, network, accounts) {and the last}
之间改变的部分。npm
在这种状况下,咱们告诉部署者部署TNSToken并传入from
参数以设置初始代币持有者。这里使用的地址是由Ganache生成的随机地址,可是经过使用自动发送给部署者的accounts
数组,咱们确保能够访问运行节点中存在的账户列表(不管是实时Geth节点仍是Ganache)。在个人特定示例中,account[0]
地址为0xdFb659D556d926dd3585d0f18d4F8eD7939E8061
,在上面的屏幕截图中也很明显。
咱们也不要忘记在truffle.js
配置开发环境:
module.exports = { networks: { development: { host: "127.0.0.1", port: 7545, network_id: "*" } } };
注意:照顾端口和IP; 你的可能会有所不一样!
最后,在项目文件夹中,运行truffle migrate
。你应该看到这样的东西:
注意TNStoken旁边的以太坊地址:0x3134bcded93e810e1025ee814e87eff252cff422
。这是咱们的代币部署的地方。如今让咱们看看它的实际效果。
在这种状况下,不须要自动测试。代币合约是高度标准化和战斗测试。若是咱们使用的某些功能超出了传统代币的范围,那么自动化测试就会派上用场。可是,经过将它发送到地址和从地址发送来测试它已经足够了。
打开像MyEtherWallet这样的钱包UI,在右上角的菜单中选择一个自定义网络。在对话框中,输入你的私有区块链给你的信息——Ganache或实际的PoA区块链,根据本教程系列的第1部分,你能够运行的任何一个。在个人例子中,地址为127.0.0.1
,端口为7545
。
打开你在部署脚本中设置为from
值的钱包。若是你正在使用Ganache,你会看到它的私钥打印在Ganache UI的屏幕上或终端的ganache输出中。
最后,须要告知MEW该代币存在。咱们经过添加自定义代币来完成此操做。
添加代币后,你会当即注意到该账户如今有1亿的余额,而且可以在货币下拉选择菜单中发送它们。咱们试着将一些发送到另外一个地址。
继续发送,而后再将原始账户恢复到1亿。咱们刚刚确保代币的基本功能按预期工做。
若是不将其部署在实时网络上,这将不是真正的代币测试。可是,咱们不要使用主网络,而是像Rinkeby这样的测试网。
在truffle.js
,让咱们添加一个新的网络rinkeby
,这样咱们的文件看起来像这样:
require('dotenv').config(); const WalletProvider = require("truffle-wallet-provider"); const Wallet = require('ethereumjs-wallet'); const Web3 = require("web3"); const w3 = new Web3(); const PRIVKEY = process.env["PRIVKEY"]; const INFURAKEY = process.env["INFURAKEY"]; module.exports = { networks: { development: { host: "127.0.0.1", port: 7545, network_id: "*" }, rinkeby: { provider: function() { return new WalletProvider( Wallet.fromPrivateKey( Buffer.from(PRIVKEY, "hex")), "https://rinkeby.infura.io/"+INFURAKEY ); }, gas: 4600000, gasPrice: w3.utils.toWei("50", "gwei"), network_id: "3", }, } };
哎呀!这都是什么?
让咱们逐行梳理它。
前几行导入一些节点模块,所以咱们可使用下面的函数。若是你获得任何一个缺乏的模块消息,只需运行npm install web3-wallet-provider truffle-wallet-provider web3 dotenv --save
应该能够解决问题。
接下来,咱们从根目录中的.env
文件中加载咱们正在运行合约钱包的私钥(因此钱包将得到1亿个代币;咱们不能在这里使用from
值)项目文件夹。若是它不存在,请建立它。该文件还有一个Infura.io
访问密钥,这是一个托管以太坊节点并容许应用程序链接到它们的网站,所以开发人员无需在其计算机上运行完整的以太坊节点。
.env
文件默认是隐藏的,能够在.gitignore
忽略,这样就不会有私钥泄漏的危险——这是一个很是重要的预防措施!这是文件包含的内容:
PRIVKEY="YOUR_PRIVATE_KEY"; INFURAKEY="YOUR_INFURA_ACCESS_KEY";
你能够在此处注册获取Infura密钥。若是你只是安装Metamask,将其切换到Rinkeby,而后转到导出私钥,则能够轻松获取私钥。可是,任何方法均可行,因此选择你喜欢的任何方法。你也可使用Ganache的私钥。一个私钥能够在全部以太坊网络上解锁相同的钱包——testnet
,rinkeby
,mainnet
,你能够命名它。
回到咱们的配置文件。咱们有一个新的network
入口:rinkeby。这是咱们将要部署的以太坊测试网的名称,提供商内部的代码基本上是千篇一概的复制粘贴,告诉Truffle“抓住个人私钥,对其进行十六进制编码,使其成为一个未锁定的钱包,而后再经过它来和Infura交互“。
最后,咱们定义了咱们但愿在执行此合约时要花费的gas限制(460万就够了,若是须要能够更改),gas须要多少(50 Gwei实际上至关昂贵,但咱们正在玩的以太网是模拟的,因此不要紧),而且将网络ID设置为4,由于这是Rinkeby testnet的标签。
还有一件事咱们须要作。咱们以前写的迁移文件是针对起始地址,但Rinkeby的地址不一样。这是否意味着咱们须要根据网络更改部署脚本?固然不是!让咱们将2_deploy_tnstoken.js
文件更改成以下所示:
var Migrations = artifacts.require("./Migrations.sol"); var TNSToken = artifacts.require("./TNSToken.sol"); module.exports = function(deployer, network, accounts) { if (network == "development") { deployer.deploy(TNSToken, {from: accounts[0}); } else { deployer.deploy(TNSToken); } };
正如你所看到的,部署脚本是简单的JavaScript,而且为部署者提供的第二个参数始终是网络的名称——咱们可使用它来区分它们。
若是咱们如今尝试使用truffle migrate --network rinkeby
运行迁移,若是咱们使用的地址是新的,它将失败:
这是由于该地址在部署合约时无需花费以太。但这很容易解决。只需前往Rinkeby Faucet免费获取一些。
如今从新运行迁移,代币合约将在Rinkeby网络上实时部署。它能够像上面的Ganache用例同样进行测试。一切都应该彻底同样,只有如今你也能够和你的朋友和同事一块儿测试。颇有进展!
对于额外的信任点,建议你在Etherscan上验证代币并为其注册ENS域。
验证意味着将代币的源代码提交给Etherscan,以便将其与网络上部署的内容进行比较,从而将其验证为无后门。这是在代币地址的“代码”选项卡上完成的。因为咱们的代币使用了一些第三方代码,而且没法轻松将这些代码拉入验证屏幕的代码窗口,所以咱们须要修改合约。为此,咱们将使用一个名为truffle-flattener
的工具:
npm install --global truffle-flattener
该工具将全部依赖项和代币的源代码复制到一个文件中。咱们能够像这样运行它:
truffle-flattener contracts/TNSToken.sol >> ./contracts/TNSTokenFlat.sol
如今,contracts
文件夹中应该存在一个新文件,几乎与咱们的源代码相同,但粘贴了依赖代码(例如,SafeMath.sol
将粘贴在文件的顶部)。
将该新文件的内容粘贴到Verify
屏幕的代码窗口中,将编译器设置为经过运行truffle version
得到的truffle版本,并将Optimization
设置为No
。单击“验证并发布”,一旦该过程完成,你的代币的地址屏幕将显示新选项卡:“读取合约”和“写入合约”,“ 代码”选项卡将具备绿色复选标记,表示代码已通过验证。这为社区提供了额外的信任点。
ENS是以太坊名称系统。它用于为以太坊提供人类可读的名称,所以你没必要记住0xmumbojumbo
字符串,而是能够记住像bitfalls.eth
这样的。而后,你甚至能够注册像token.bitfalls.eth
这样的子域名。注册ENS域的过程并不简单,须要时间,所以若是你愿意这样作,我建议你阅读本指南并按照此处的说明进行操做。
在这一部分中,咱们进行了编译和部署自定义代币。此代币与全部交易所兼容,可用做常规ERC20代币。
======================================================================
分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:
- java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
- python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
- php以太坊,主要是介绍使用php进行智能合约开发交互,进行帐号建立、交易、转帐、代币开发以及过滤器和交易等内容。
- 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
- 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
- C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括帐户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
- EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、帐户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
- java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如建立地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
- php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如建立地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
- tendermint区块链开发详解,本课程适合但愿使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。
汇智网原创翻译,转载请标明出处。这里是原文以太坊构建DApps系列教程(三):编译部署测试TNS代币