上一篇博客中我尝试搭建了单节点的sawtooth网络,但是对于单节点网络是不存在共识的,而共识是区块链保证安全性的重要机制,因此这一篇博客将会使用docker来搭建拥有5个节点的sawtooth环境,每个节点都是一系列Docker容器的集合,在其中运行验证者和相关的sawtooth组件,虽说是5个节点,但搭建过程和1个节点差不多,大部分工作都被封装了。
整个实验过程包括如下内容;
- 下载Sawtooth docker-compose文件
- 使用docker-compose启动sawtooth网络
- 检查处理状态
- 配置允许的交易类型
- 连接sawtooth脚本容器以及确认网络的功能
- 停止与重置sawtooth docker环境
整个网络环境如下:
可以看到,网络中有5个节点,其中每个节点都和单节点Sawtooth环境时相同,唯一的区别是如果网络使用了PoET共识方法,需要部署交易族poet-validator-registry-tp
来配置PoET共识以及在多节点环境下处理网络。
和单节点sawtooth相似的地方是当前环境仍然使用了多个交易处理器,区别是使用了真正的共识算法,单节点中使用的是Devmode consensum(可能是根本没有共识),而在多节点环境中则使用PBFT或者PoET共识,这两种共识都是容错的。
第一个节点创建创世块(genesis block),来指明网络的连上配置,其他节点加入网络时需要访问这些设置。
步骤1.下载Docker Compose文件
如果是PBFT,下载sawtooth-default-pbft.yaml
如果是PoET,则下载sawtooth-default-poet.yaml
这里我使用PBFT共识算法,即下载第一个文件。
步骤2.启动sawtooth网络
打开终端,切换到刚才yaml文件的下载路径。
cd /home/xxx/sawtooth/network
如果下载的是PBFT的共识文件,使用如下命令启动:
docker-compose -f sawtooth-default-pbft.yaml up
如果是PoET,则用如下命令:
docker-compose -f sawtooth-default-poet.yaml up
这里会创建5个Sawtooth节点,每个节点包含若干个容器,和单节点启动时分别对应,命名方式为"容器名称-编号",此外还包括一个shell容器,名称为sawtooth-shell-default
。
步骤3.检查REST API 运行情况
这里可以选择一个API容器进行连接,然后使用ps命令查看当前进程号为1的进程。
docker exec -it sawtooth-rest-api-default-0 bash
ps --pid 1 fw
打印出如下内容,说明运行正常。
root@f4c6a5ba76dd:/# ps --pid 1 fw
PID TTY STAT TIME COMMAND
1 ? Ssl 0:01 /usr/bin/python3 /usr/bin/sawtooth-rest-api --connect tcp://validator-0:4004 --bind rest-api-0:8008
说明REST API本质上是一个python程序,运行在容器中。
步骤4.确定网络功能
首先连接到shell容器中。
docker exec -it sawtooth-shell-default bash
为了查看是否已经形成了对等网络,可以向第一个节点提交peer查询,该命令需要指定docker容器名称和端口。
curl http://sawtooth-rest-api-default-0:8008/peers
如果查询返回503错误,说明节点还没有形成对等网络,需要重复查询工作直到出现如下的输出。
{
"data": [
"tcp://validator-4:8800",
"tcp://validator-3:8800",
...
"tcp://validator-2:8800",
"tcp://validator-1:8800"
],
"link": "http://sawtooth-rest-api-default-0:8008/peers"
其中,data输出的即为node0对应的所有peer。
然后可以提交一个Integer Key交易族的交易,设置一个字符串到数值的映射:
intkey set --url http://sawtooth-rest-api-default-0:8008 MyKey 999
输出正常情况下应该是这样:
{
"link": "http://sawtooth-rest-api-default-0:8008/batch_statuses?id=a228d8be3a75f5fe3a2772c9dee7a05fc7255ceb0f59821e3ed03013dcaa43600a9050aece4e1bb58ace96146896983cac15836cb9a64c9480ea8acffa0b5c0f"
}
为了查看交易的执行情况,可以从另一个节点(sawtooth-rest-api-default-1)去查看MyKey对应的值,即在容器中运行如下命令:
intkey show --url http://sawtooth-rest-api-default-1:8008 MyKey
可以看到如下输出:
MyKey: 999
说明交易成功执行。
步骤5.配置允许的交易类型(可选)
默认情况下,验证者会接收任何交易处理器的交易,但是可以通过配置sawtooth来限制可提交的交易类型。
这里我们会对其进行配置来让他们只接受运行在测试环境中的交易处理器对应的交易类型。进行设置时,设置首先会被应用在一个节点上,然后才会被应用到其他所有节点上。
具体设置则是通过Setting transaction处理器实现的,该处理器负责处理链上配置交易。需要使用sawset
命令来创建和提交包含配置变更的交易批次。
首先需要连接到第一个验证者容器,因为之后的命令需要在这个容器中生成的验证者密钥。
docker exec -it sawtooth-validator-default-0 bash
然后可以用如下的命令来进行具体的设置。
PBFT:
sawset proposal create --url http://sawtooth-rest-api-default-0:8008 --key /etc/sawtooth/keys/validator.priv \
sawtooth.validator.transaction_families='[{"family": "intkey", "version": "1.0"}, {"family":"sawtooth_settings", "version":"1.0"}, {"family":"xo", "version":"1.0"}]'
PoET:
sawset proposal create --url http://sawtooth-rest-api-default-0:8008 --key /etc/sawtooth/keys/validator.priv \
sawtooth.validator.transaction_families='[{"family": "intkey", "version": "1.0"}, {"family":"sawtooth_settings", "version":"1.0"}, {"family":"xo", "version":"1.0"}, {"family":"sawtooth_validator_registry", "version":"1.0"}]'
这里以JSON格式限定的交易族均为当前在链上部署的交易处理器对应的交易族。
为了查看设置的效果,可以运行如下命令:
sawtooth settings list --url http://sawtooth-rest-api-default-0:8008
可以看到输出为:
sawtooth.settings.vote.authorized_keys: 0313aea85e836973977828ba04a907970f7346eef692b3389c40c854e29510e867
sawtooth.validator.transaction_families: [{"family": "intkey", "version": "1.0"}, {"family":"sawtooth_settings", "version":"1.0"}, {"family":"xo", "version":"1.0"}]
这里可以看到允许的链码族为我们刚设置的这些。
步骤6.停止网络运行
首先进入yaml所在路径,然后运行对应的docker-compose命令。
cd /home/xxx/sawtooth/network
对于PBFT:
docker-compose -f sawtooth-default-pbft.yaml down
对于PoET:
docker-compose -f sawtooth-default-poet.yaml down