搭建一个私有的EOS集群

单producer测试节点的搭建

EOS (Enterprise Operation System)是由 Block.one公司主导开发的一种全新的基于区块链智能合约平台,由区块链奇才 BM (Daniel Larimer)领导开发。旨在为高性能分布式应用提供底层区块链平台服务。EOS 项目的目标是实现一个类似操作系统的支撑分布式应用程序的区块链架构。该架构可以提供账户,身份认证,数据库,异步通信以及可在数以万计的 CPU/GPU群集上进行程序调度和并行运算。EOS最终可以支持每秒执行数百万个交易,同时普通用户执行智能合约无需支付使用费用。

Block.one团队人才济济,包括Brendan Blummer(之前的公司交易MMORPG游戏货币)、首席科技官Daniel Larimer(区块链传奇人物之一,下面会介绍)和Brock Pierce(区块链基金会主席,Blockchain Capital联合创始人)等等。

2017年6月26日,Block.one开始销售EOS代币,计划355天共销售10亿EOS代币,EOS主网上线后会将这个以太坊基础版本的代币EOS转换为其主链上的代币。

2017年6月26-30日,销售20%也就是2亿代币,5天融资1.85亿美元,打破了当时ICO的世界纪录。70%接下来会以每小时23小时200万个发售。发售期间始于7月1号,剩下的持续350天。剩余的10%留属Block.one,不能交易和转让。每年新产生最多5%用于做DPoS的奖励。

EOS 项目刚刚发布的时候的共识机制是 DPoS(Deligated Proof of Stake,委托股权证明),类似于 Bitshares 和 Steem,这种共识机制采用随机的见证人出块顺序,出块速度为 3 秒,交易不可逆需要45秒。

EOS 最新的白皮书中已经将共识机制从 DPoS 升级为了 BFT-DPoS(Byzantine Fault Tolerance – Deligated Proof of Stake,带有拜占庭容错的委托股权证明)。交易确认时间大大缩短,从 45 秒缩短至 3 秒左右(主要为等待生产区块的时间)。这种机制可以称为初级版的 BFT-DPoS 共识机制。Daniel Larimer 称 EOS 新的 BFT-DPoS 共识机制还在开发中,会在系统上线前完成开发。

EOS组件

EOS包括三个组件:

  • nodeos: 管理区块链节点的组件
  • keosd:管理钱包的组件
  • cleos:控制区块链和钱包CLI工具

数据结构

  • block包含交易(transaction)
  • 交易包含一组要执行的Action
  • Action代表智能合约(smart contract)

Tx内容

下面我们介绍如何在MacOSX/Centos 7上编译、运行一个私有的EOS集群, 并进行相应的的测试。

编译

编译可以让你更好的了解和定制EOS, 当然你可以使用docker镜像运行这三个组件。Docker镜像的运行方法可以参考Docker Quickstart

首先下载源代码

将代码clone到本地。

1
git clone https://github.com/EOSIO/eos --recursive

如果你不使用--recursive参数, 你需要在eos文件夹下运行git submodule update --init --recursive

编译

EOS可以支持在以下操作系统进行编译:

  • Amazon 2017.09 and higher.
  • Centos 7.
  • Fedora 25 and higher (Fedora 27 recommended).
  • Mint 18.
  • Ubuntu 16.04 (Ubuntu 16.10 recommended).
  • MacOS Darwin 10.12 and higher (MacOS 10.13.x recommended).

进入eos文件夹并执行编译:

1
2
cd eos
./eosio_build.sh

编译完之后进行安装

1
./eosio_install.sh

在编译的过程中,会检查相应的依赖库,你需要根据提示安装对应的版本。有些库比如boost、llvm,你可能需要使用brew卸载重新安装所需的版本。
在编译的过程中会有些问题,但是基本上对应的问题都可以在EOS的github issues找的到对应的issue和解决方案,你只需按照关键字在issue搜索就能找到答案,因为别人已经趟过对应的坑了。

编译完成后会显示下图:
编译成功

测试

首先需要启动mongodb:

1
/usr/local/bin/mongod -f /usr/local/etc/mongod.conf &

然后运行测试:

1
2
cd build
make test

安装

执行下面的脚本进行安装

1
./eosio_install.sh

安装各个组件

配置一个节点的私有testnet网络

单节点测试网络

编译完eos的代码, nodeos存在于build/programs/nodeos, 或者你执行安装后,nodeos应该存在于你的系统二进制文件夹中。

为了统一描述,我们假定相关的组件和工具都已经安装到系统文件夹中了,否则你需要到build/programs相应的文件夹下去找。

运行一个nodeos节点:

1
nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin

可以看到相关的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@dbl14195 eos]# nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin
info 2018-11-21T06:19:25.227 thread-0 chain_plugin.cpp:333 plugin_initialize ] initializing chain plugin
warn 2018-11-21T06:19:25.227 thread-0 chain_plugin.cpp:605 plugin_initialize ] Starting up fresh blockchain with default genesis state.
info 2018-11-21T06:19:25.228 thread-0 http_plugin.cpp:422 plugin_initialize ] configured http to listen on 127.0.0.1:8888
info 2018-11-21T06:19:25.229 thread-0 net_plugin.cpp:2901 plugin_initialize ] Initialize net plugin
info 2018-11-21T06:19:25.229 thread-0 net_plugin.cpp:2927 plugin_initialize ] host: 0.0.0.0 port: 9876
info 2018-11-21T06:19:25.229 thread-0 net_plugin.cpp:2998 plugin_initialize ] my node_id is 9441e3999bcfe8ff1d69ea77c817f5848fe25d9570f6d6e0ba3ea8365c17c6af
info 2018-11-21T06:19:25.229 thread-0 main.cpp:110 main ] nodeos version v1.4.4
info 2018-11-21T06:19:25.229 thread-0 main.cpp:111 main ] eosio root is /root/.local/share
info 2018-11-21T06:19:25.229 thread-0 main.cpp:112 main ] nodeos using configuration file /root/.local/share/eosio/nodeos/config/config.ini
info 2018-11-21T06:19:25.229 thread-0 main.cpp:113 main ] nodeos data directory is /root/.local/share/eosio/nodeos/data
error 2018-11-21T06:19:25.229 thread-0 controller.cpp:1596 startup ] No head block in fork db, perhaps we need to replay
warn 2018-11-21T06:19:25.229 thread-0 controller.cpp:574 initialize_fork_db ] Initializing new blockchain with genesis state

上面的日志中我们可以看到配置文件和数据文件夹的位置,

1
2
3
info 2018-11-21T06:19:25.229 thread-0 main.cpp:111 main ] eosio root is /root/.local/share
info 2018-11-21T06:19:25.229 thread-0 main.cpp:112 main ] nodeos using configuration file /root/.local/share/eosio/nodeos/config/config.ini
info 2018-11-21T06:19:25.229 thread-0 main.cpp:113 main ] nodeos data directory is /root/.local/share/eosio/nodeos/data

MacOS和Linux的位置不一样:

  • Mac OS: ~/Library/Application\ Support/eosio/nodeos/config
  • Linux: ~/.local/share/eosio/nodeos/config

你可以在在启动时指定配置文件夹和数据文件,所有的其它配置都放在配置文件中:

1
nodeos -d eos1/data --config-dir eos1/config

这样就会在eos1/config创建一个配置文件config.ini, 你可以修改这个配置文件,比如下面的修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# the endpoint upon which to listen for incoming connections (eosio::bnet_plugin)
bnet-endpoint = 0.0.0.0:44321
# The local IP and port to listen for incoming http connections; set blank to disable. (eosio::http_plugin)
http-server-address = 0.0.0.0:48888
# The actual host:port used to listen for incoming p2p connections. (eosio::net_plugin)
p2p-listen-endpoint = 0.0.0.0:49876
# Enable block production, even if the chain is stale. (eosio::producer_plugin)
enable-stale-production = true
# ID of producer controlled by this node (e.g. inita; may specify multiple times) (eosio::producer_plugin)
producer-name = eosio
signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
plugin = eosio::producer_plugin
plugin = eosio::chain_api_plugin
plugin = eosio::http_plugin
plugin = eosio::history_api_plugin

它默认使用producereosio, 公私钥为EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3的producer。

你可以使用创建一个不同的私钥:

1
2
3
[root@dbl14195 eos]# cleos create key --to-console
Private key: 5JKHs4Bxwpog77bsThweEPaUsn86PpKN2gaHuWF9nKJGzvkAC6s
Public key: EOS7X4tiDD9gjrMDfMY2xtXLznmBXwi31NdecYju8VJQYTyCGoibq

这里我们配置的是producer节点,它可以产生block。 我们还可以创建非producer节点, 非producer节点就不需压迫配置producer-namesignature-provider,并且producer_plugin插件页不需要了。

启动keosd

为了使用钱包,你需要启动keosd, 这里我们指定配置文件的路径和数据路径, 如果配置文件不存在,会创建一个。

1
keosd -d wallet/data --config-dir wallet/config

修改配置文件wallet/config/config.ini, 配置http监听地址,然后重启keosd:

1
http-server-address = 127.0.0.1:8899

创建钱包

nodeoskeosd既然已经启动,我们就可以创建我们自己的钱包了。

创建一个可管理的钱包

1
2
3
4
5
[root@dbl14195 eos]# cleos --wallet-url http://127.0.0.1:8899 wallet create --to-console
Creating wallet: default
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5JbeAsfCHJqNwv7fGhDVPb94L5cKtcrfPFXYxG7U9jiYG9pUNtn"

-n可以指定钱包的名称,不指定的话创建default钱包。
这个密码PW5JbeAsfCHJqNwv7fGhDVPb94L5cKtcrfPFXYxG7U9jiYG9pUNtn很重要,它用来解锁钱包,不要弄丢了。

使用下面的命令可以解锁这个钱包:

1
cleos --wallet-url http://127.0.0.1:8899 wallet unlock -n default --password PW5JbeAsfCHJqNwv7fGhDVPb94L5cKtcrfPFXYxG7U9jiYG9pUNtn

创建账号

1、 在创建账号之前,我们需要为账号创建密钥

1
2
3
cleos create key --to-console
Private key: 5KTXFtDCRvo9GkB9tQZTcoygFJCMgNyyXMFddUu9k3o1R2Vm954
Public key: EOS6CrKkykBfRkiqS5kkbhjVHhnQFxf8YuwtVqQgrso4GniesqPcG

2、 将这个私钥导入到钱包

1
2
[root@dbl14195 eos]# cleos --wallet-url http://127.0.0.1:8899 wallet import --private-key 5KTXFtDCRvo9GkB9tQZTcoygFJCMgNyyXMFddUu9k3o1R2Vm954
imported private key for: EOS6CrKkykBfRkiqS5kkbhjVHhnQFxf8YuwtVqQgrso4GniesqPcG

3、创建账号

cleos create account 用来创建boot的时候的账号, 比如
eosio.bpay
eosio.msig
eosio.names
eosio.ram
eosio.ramfee
eosio.saving
eosio.stake
eosio.token
eosio.vpay

cleos system newaccount用来创建普通账号,
本文下面演示使用cleos create account创建账号。
If the system contract isn't running, then accounts don't need to buy ram or stake resources. cleos create account works in this mode.

If the system contract is running, then accounts need enough ram to hold the account information. They also need staked resources to cover any transactions they sign. cleos system newaccount takes care of these issues.

我们要创建一个新的账号,需要由某个账号签名,所以还需要将创建账号的私钥导入到钱包。我们刚才配置了一个producer为eosio的初始账号,
所以我们使用它来创建账号。(创建账号为eosio, 待创建账号为admin1)

导入eosio的私钥,你可以查看eos1/config/config.ini中的配置:

1
2
[root@dbl14195 eos]# cleos --wallet-url http://127.0.0.1:8899 wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
imported private key for: EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV

这样我们就可以使用eosio创建其他的账号了,比如下面我们创建一个admin1的账号:

1
2
3
4
[root@dbl14195 eos]# cleos --wallet-url http://127.0.0.1:8899 -u http://127.0.0.1:48888 create account eosio admin1 EOS6CrKkykBfRkiqS5kkbhjVHhnQFxf8YuwtVqQgrso4GniesqPcG
executed transaction: f8709ffa53e2855f7d489570501cb491c28d3681e83b5e421a564449b4ff02c7 200 bytes 477 us
# eosio <= eosio::newaccount {"creator":"eosio","name":"admin1","owner":{"threshold":1,"keys":[{"key":"EOS6CrKkykBfRkiqS5kkbhjVHh...
warning: transaction executed locally, but may not be confirmed by the network yet ]

因为我们需要将交易发送到我们的测试网络上,所以这里需要指定nodeos节点的http地址http://127.0.0.1:48888

4、下面再创建另外一个账号admin2

这次使用admin1创建:

首先生成一个私钥:

1
2
3
[root@dbl14195 eos]# cleos create key --to-console
Private key: 5K5V8eH68nzcmTkzYRWHBvgEtzKo5SJDu57DcrXFmszoHCQnUzF
Public key: EOS6FF1ByAGfNEbx1okMiKjeKq9FeNQvybz7pPTWqpJ7vwxDatDiS

提交创建账号的交易:

1
2
3
4
[root@dbl14195 eos]# cleos --wallet-url http://127.0.0.1:8899 -u http://127.0.0.1:48888 create account admin1 admin2 EOS6FF1ByAGfNEbx1okMiKjeKq9FeNQvybz7pPTWqpJ7vwxDatDiS
executed transaction: 150b435cadbad3fe2cc228f9a9808520b81b605c0b8fa11a7461babd3dc570f8 200 bytes 392 us
# eosio <= eosio::newaccount {"creator":"admin1","name":"admin2","owner":{"threshold":1,"keys":[{"key":"EOS6FF1ByAGfNEbx1okMiKjeK...
warning: transaction executed locally, but may not be confirmed by the network yet ]

如果想用本地的钱包管理这个账号, 那么我们可以导入这个私钥:

1
2
[root@dbl14195 eos]# cleos --wallet-url http://127.0.0.1:8899 wallet import --private-key 5K5V8eH68nzcmTkzYRWHBvgEtzKo5SJDu57DcrXFmszoHCQnUzF
imported private key for: EOS6FF1ByAGfNEbx1okMiKjeKq9FeNQvybz7pPTWqpJ7vwxDatDiS

现在已经创建了两个账号admin1admin2,并且都导入了本地钱包:

1
2
3
4
5
6
[root@dbl14195 eos]# cleos --wallet-url http://127.0.0.1:8899 -u http://127.0.0.1:48888 wallet keys
[
"EOS6CrKkykBfRkiqS5kkbhjVHhnQFxf8YuwtVqQgrso4GniesqPcG",
"EOS6FF1ByAGfNEbx1okMiKjeKq9FeNQvybz7pPTWqpJ7vwxDatDiS",
"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
]

参考文档

  1. https://eos.io
  2. https://developers.eos.io/eosio-nodeos/docs/overview-1
  3. https://developers.eos.io/eosio-nodeos/docs/local-single-node-testnet
  4. https://developers.eos.io/eosio-nodeos/docs/local-multi-node-testnet
  5. https://developers.eos.io/eosio-nodeos/docs/bios-boot-sequence
  6. https://medium.com/coinmonks/building-dapps-with-eos-io-uw-workshop-29ec6fcbd505
  7. https://en.wikipedia.org/wiki/EOS.IO
  8. https://www.damenginfo.com/982.html
  9. https://www.jianshu.com/p/0b2f855b23bc
  10. https://mp.weixin.qq.com/s?__biz=MzU5MzMxNTk2Nw==&mid=2247483899&idx=1&sn=5ddaead86b2c1950305b4a6a2be91295&chksm=fe1310ebc96499fd
  11. https://blog.csdn.net/bedrock_stable/article/details/80318178
  12. https://eoswiki.readthedocs.io/zh_CN/latest/智能合约入门/
  13. http://www.hestart.com/2018/08/30/eos-quick-start/
  14. https://github.com/EOSIO/eos/issues/5453