EOS 如何安装本地多节点测试开发环境

本教程介绍如何在单个主机上建立多节点区块链配置。这被称为单主机多节点测试网。我们将在本地计算机上设置两个节点,并让它们相互通信。本节中的示例依赖于三个命令行应用程序nodeoskeosdcleos。下面的图表描述了所需的testnet配置。

假设nodeoskeosdcleos已经安装在你的目录中,或者你知道如何从文件系统中的位置启动这些应用程序。如果不了解可以先看下[设置本地环境(http://blog.hubwiz.com/2018/07/23/EOS-development-environment/)

打开四个“终端”窗口来执行本教程中的各个步骤。

启动钱包管理应用程序keosd

在第一终端窗口中,启动keosd,钱包管理应用程序:

1
keosd --http-server-address 127.0.0.1:8899

如果成功,keosd将显示一些信息:

1
2
3
4
5
2493323ms thread-0   wallet_plugin.cpp:39          plugin_initialize    ] initializing wallet plugin
2493323ms thread-0 http_plugin.cpp:141 plugin_initialize ] host: 127.0.0.1 port: 8899
2493323ms thread-0 http_plugin.cpp:144 plugin_initialize ] configured http to listen on 127.0.0.1:8899
2493323ms thread-0 http_plugin.cpp:213 plugin_startup ] start listening for http requests
2493324ms thread-0 wallet_api_plugin.cpp:70 plugin_startup ] starting wallet_api_plugin

找到一行说钱包在监听127.0.1:8899。这说明keosd正确启动并正在正确的端口上监听。如果你看到其他的内容,或者你在“starting wallet_api_plugin”之前看到一些错误报告,那么你需要诊断那个问题并重新启动。

keosd运行正常时,让该窗口始终打开,钱包管理应用程序运行,并移动到下一个终端窗口。

创建一个默认钱包

在下一个终端窗口中,使用cleos命令行实用程序来创建默认的钱包。

1
cleos --wallet-url http://localhost:8899  wallet create

cleos将显示它创建了“默认”钱包,并为未来钱包访问提供密码。正如提示信息所说的,一定要保留这个密码以备将来使用。下面是这个输出的例子:

1
2
3
4
Creating wallet: default
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5JsmfYz2wrdUEotTzBamUCAunAA8TeRZGT57Ce6PkvM12tre8Sm"

keosd将在其窗口中产生一些状态输出。我们将继续使用第二个窗口来完成cleos命令。

加载eosio密钥

在上面的步骤中启动的私有区块链是用一个默认的初始密钥创建的,它必须被加载到钱包中。

1
2
$ cleos wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
imported private key for: EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV

启动第一个生产节点

现在我们可以启动第一个生产节点。在第三终端窗口运行:

1
nodeos --enable-stale-production --producer-name eosio --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin

这就产生了一个特殊的生产者,被称为“bios”生产者。假设所有的事情都是正确,执行到这一点,你应该看到nodeos进程输出块的创建报告。

启动第二个生产者节点

下面的命令假定你正在从${EOSIO_SOURCE}目录运行此教程,在目录中运行./eosio_build.sh以构建。如果不了清楚看下[设置本地环境(http://blog.hubwiz.com/2018/07/23/EOS-development-environment/)

若要启动其他节点,必须首先加载eosio.bios合约。此合约使你能够直接控制其他帐户的资源分配,并调用其他需要授权的API。返回到第二个终端窗口并运行下面的命令来加载合约:

1
cleos --wallet-url http://localhost:8899 set contract eosio build/contracts/eosio.bios

我们将使用帐户名inita创建一个帐户成为生产者。要创建帐户,我们需要生成与帐户关联的密钥,并将这些导入到我们的钱包中。

运行创建键命令:

1
cleos create key

这将输出新生成的公钥和私钥对,它们看起来类似于下面的内容:

重要提示:下面的命令行指令使用下面所示的密钥。为了能够直接从本教程中剪切和粘贴命令行指令,不要使用刚才生成的密钥。相反,如果要使用新生成的密钥,则需要用你在命令中的密钥替换本文的密钥值。

1
2
Private key: 5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr
Public key: EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg

现在将私钥部分导入到钱包中。如果成功,将输出匹配的公钥。这应该与先前生成的公钥一致:

1
2
cleos --wallet-url http://localhost:8899 wallet import 5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr
imported private key for: EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg

创建完成后我们成为生产者的inita帐户。create account需要两个公共密钥,一个用于帐户的所有者密钥,一个用于激活密钥。在这个例子中,新创建的公钥被使用两次,作为所有者密钥和激活密钥。下面显示来自create命令的示例输出:

1
2
3
cleos --wallet-url http://localhost:8899 create account eosio inita EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg
executed transaction: d1ea511977803d2d88f46deb554f5b6cce355b9cc3174bec0da45fc16fe9d5f3 352 bytes 102400 cycles
# eosio <= eosio::newaccount {"creator":"eosio","name":"inita","owner":{"threshold":1,"keys":[{"key":"EOS6hMjoWRF2L8x9YpeqtUEcsDK...

我们现在有一个帐户,可以有一个合约分配给它,使它能够做有意义的工作。在其他教程中,帐户已被用来建立简单的合约。在这种情况下,帐户将被指定为块生产者。

在第四终端窗口中,启动第二个nodeos实例。注意,这个命令行比我们用来创建第一个生产者的命令行要长得多。这是避免与第一个nodeos实例冲突的必要条件。幸运的是,你可以剪切并粘贴此命令行并调整密钥即可:

1
nodeos --producer-name inita --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin --http-server-address 127.0.0.1:8889 --p2p-listen-endpoint 127.0.0.1:9877 --p2p-peer-address 127.0.0.1:9876 --config-dir node2 --data-dir node2 --private-key [\"EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg\",\"5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr\"]

这个新节点的输出将显示一点活动,但在本教程的最后一步,当inita帐户注册为生产者帐户并被激活时,将停止输出。下面是从新启动的节点输出的一些示例。你的输出可能看起来有点不同,取决于你输入这些命令的时间。此外,这个示例只是输出的最后几行:

1
2
3
4
5
6
7
8
9
2393147ms thread-0   producer_plugin.cpp:176       plugin_startup       ] producer plugin:  plugin_startup() end
2393157ms thread-0 net_plugin.cpp:1271 start_sync ] Catching up with chain, our last req is 0, theirs is 8249 peer dhcp15.ociweb.com:9876 - 295f5fd
2393158ms thread-0 chain_controller.cpp:1402 validate_block_heade ] head_block_time 2018-03-01T12:00:00.000, next_block 2018-04-05T22:31:08.500, block_interval 500
2393158ms thread-0 chain_controller.cpp:1404 validate_block_heade ] Did not produce block within block_interval 500ms, took 3061868500ms)
2393512ms thread-0 producer_plugin.cpp:241 block_production_loo ] Not producing block because production is disabled until we receive a recent block (see: --enable-stale-production)
2395680ms thread-0 net_plugin.cpp:1385 recv_notice ] sync_manager got last irreversible block notice
2395680ms thread-0 net_plugin.cpp:1271 start_sync ] Catching up with chain, our last req is 8248, theirs is 8255 peer dhcp15.ociweb.com:9876 - 295f5fd
2396002ms thread-0 producer_plugin.cpp:226 block_production_loo ] Previous result occurred 5 times
2396002ms thread-0 producer_plugin.cpp:244 block_production_loo ] Not producing block because it isn't my turn, its eosio

在这一点上,第二个节点是一个闲置生产者。为了将其转换为活动的生产者,需要将inita注册为具有bios节点的生产者,并且bios节点需要执行动作来更新生产者计划。

1
2
3
cleos --wallet-url http://localhost:8899 push action eosio setprods "{ \"schedule\": [{\"producer_name\": \"inita\",\"block_signing_key\": \"EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg\"}]}" -p eosio@active
executed transaction: 2cff4d96814752aefaf9908a7650e867dab74af02253ae7d34672abb9c58235a 272 bytes 105472 cycles
# eosio <= eosio::setprods {"version":1,"producers":[{"producer_name":"inita","block_signing_key":"EOS6hMjoWRF2L8x9YpeqtUEcsDKA...

祝贺你,你现在已经配置了两个节点testnet!可以看到原始节点不再生成块,而是正在接收它们。可以通过对每个节点运行get_info命令共享来验证这一点。

1
cleos get info

类似输出如下所示:

1
2
3
4
5
6
7
8
{
"server_version": "223565e8",
"head_block_num": 11412,
"last_irreversible_block_num": 11411,
"head_block_id": "00002c94daf7dff456cd940bd585c4d9b38e520e356d295d3531144329c8b6c3",
"head_block_time": "2018-04-06T00:06:14",
"head_block_producer": "inita"
}

现在看看第二个节点:

1
cleos --url http://localhost:8889 get info

类似输出如下所示:

1
2
3
4
5
6
7
8
{
"server_version": "223565e8",
"head_block_num": 11438,
"last_irreversible_block_num": 11437,
"head_block_id": "00002cae32697444fa9a2964e4db85b5e8fd4c8b51529a0c13e38587c1bf3c6f",
"head_block_time": "2018-04-06T00:06:27",
"head_block_producer": "inita"
}

在以后的教程中,我们将探讨如何使用更高级的工具来运行多主机、多节点testnet.

====================================================================

交互式的在线编程实战,《EOS智能合约与DApp开发入门》上线了:

EOS教程

本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。

另外有一些以太坊的课程,有兴趣也可以看看:

  • web3j教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • 以太坊教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和事件等内容。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和事件等。

汇智网原创翻译,转载请标明出处。原文