以太坊构建DApps系列教程(三):编译部署测试TNS代币

在本系列关于使用以太坊构建DApps教程的第2部分,我们编写了TNS代币的代码。但我们尚未编译,部署,测试或验证它。让我们在这一部分做这些工作,以便我们为下一步做好准备。

编译

此时我们有一个包含一些Solidity代码的文件。但为了使以太坊虚拟机能够理解它,我们需要将其转化为机器代码。另外,为了从Web应用程序与它进行通信,我们需要一个ABI(应用程序二进制接口),它是对某个智能合约中存在的函数的通用可读描述——无论是代币还是更复杂的东西。我们可以使用Truffle的编译器立即为EVM和ABI创建机器代码。

在项目文件夹中,运行:

1
truffle compile

此命令将查看contracts子文件夹内部,将它们全部编译并将其编译后的版本放入build子文件夹中。请注意,如果你使用了上一部分的替代开发流程,那么我们的TNSToken合约继承功能的所有父合约也将在其自己的文件中逐个编译。

Compile contracts

随意检查生成的JSON文件的内容。我们的TNSToken应该有超过10000行的JSON代码。

部署到Ganache

现在让我们看看是否可以将它部署到我们的仿真模拟器Ganache区块链中。如果Ganache尚未在终端的选项卡中或操作系统的应用程序中运行,请运行以下命令:

1
ganache-cli

或运行应用程序以获得这样的屏幕:

Ganache UI

然后,回到我们刚刚编译合约的文件夹中,我们必须添加一个migration迁移。创建文件migrations/2_deploy_tnstoken.js。如果你不熟悉Truffle生态系统中的迁移,请参阅本指南

我们将以下内容放入该文件中:

1
2
3
4
5
6
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}之间改变的部分。

在这种情况下,我们告诉部署者部署TNSToken并传入from参数以设置初始代币持有者。这里使用的地址是由Ganache生成的随机地址,但是通过使用自动发送给部署者的accounts数组,我们确保可以访问运行节点中存在的帐户列表(无论是实时Geth节点还是Ganache)。在我的特定示例中,account[0]地址为0xdFb659D556d926dd3585d0f18d4F8eD7939E8061,在上面的屏幕截图中也很明显。

我们也不要忘记在truffle.js配置开发环境:

1
2
3
4
5
6
7
8
9
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

在MEW中配置网络

打开你在部署脚本中设置为from值的钱包。如果你正在使用Ganache,你会看到它的私钥打印在Ganache UI的屏幕上或终端的ganache输出中。

可以在Ganache UI中访问私钥

最后,需要告知MEW该代币存在。我们通过添加自定义代币来完成此操作。

在MEW中添加自定义代币

添加代币后,你会立即注意到该帐户现在有1亿的余额,并且能够在货币下拉选择菜单中发送它们。我们试着将一些发送到另一个地址。

发送一些代币

交易正在准备中

已收到代币

继续发送,然后再将原始帐户恢复到1亿。我们刚刚确保代币的基本功能按预期工作。

部署到实时网络

如果不将其部署在实时网络上,这将不是真正的代币测试。但是,我们不要使用主网络,而是像Rinkeby这样的测试网。

truffle.js,让我们添加一个新的网络rinkeby,这样我们的文件看起来像这样:

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
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忽略,这样就不会有私钥泄漏的危险——这是一个非常重要的预防措施!这是文件包含的内容:

1
2
PRIVKEY="YOUR_PRIVATE_KEY";
INFURAKEY="YOUR_INFURA_ACCESS_KEY";

你可以在此处注册获取Infura密钥。如果你只是安装Metamask,将其切换到Rinkeby,然后转到导出私钥,则可以轻松获取私钥。但是,任何方法都可行,所以选择你喜欢的任何方法。你也可以使用Ganache的私钥。一个私钥可以在所有以太坊网络上解锁相同的钱包——testnetrinkebymainnet,你可以命名它。

回到我们的配置文件。我们有一个新的network入口:rinkeby。这是我们将要部署的以太坊测试网的名称,提供商内部的代码基本上是千篇一律的复制粘贴,告诉Truffle“抓住我的私钥,对其进行十六进制编码,使其成为一个未锁定的钱包,然后再通过它来和Infura交互“。

最后,我们定义了我们希望在执行此合约时要花费的gas限制(460万就够了,如果需要可以更改),gas需要多少(50 Gwei实际上相当昂贵,但我们正在玩的以太网是模拟的,所以没关系),并且将网络ID设置为4,因为这是Rinkeby testnet的标签。

还有一件事我们需要做。我们之前写的迁移文件是针对起始地址,但Rinkeby的地址不同。这是否意味着我们需要根据网络更改部署脚本?当然不是!让我们将2_deploy_tnstoken.js文件更改为如下所示:

1
2
3
4
5
6
7
8
9
10
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测试以太

现在重新运行迁移,代币合约将在Rinkeby网络上实时部署。它可以像上面的Ganache用例一样进行测试。一切都应该完全一样,只有现在你也可以和你的朋友和同事一起测试。很有进展!

奖励:验证和ENS

对于额外的信任点,建议你在Etherscan上验证代币并为其注册ENS域。

验证

验证意味着将代币的源代码提交给Etherscan,以便将其与网络上部署的内容进行比较,从而将其验证为无后门。这是在代币地址的“代码”选项卡上完成的。由于我们的代币使用了一些第三方代码,并且无法轻松将这些代码拉入验证屏幕的代码窗口,因此我们需要修改合约。为此,我们将使用一个名为truffle-flattener的工具:

1
npm install --global truffle-flattener

该工具将所有依赖项和代币的源代码复制到一个文件中。我们可以像这样运行它:

1
truffle-flattener contracts/TNSToken.sol >> ./contracts/TNSTokenFlat.sol

现在,contracts文件夹中应该存在一个新文件,几乎与我们的源代码相同,但粘贴了依赖代码(例如,SafeMath.sol将粘贴在文件的顶部)。

将该新文件的内容粘贴到Verify屏幕的代码窗口中,将编译器设置为通过运行truffle version获得的truffle版本,并将Optimization设置为No。单击“验证并发布”,一旦该过程完成,你的代币的地址屏幕将显示新选项卡:“读取合约”和“写入合约”,“ 代码”选项卡将具有绿色复选标记,表示代码已经过验证。这为社区提供了额外的信任点。

代币现在标记为受信任

ENS

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代币