Substrate之旅4:基于Substrate私有链的搭建

参考:https://docs.substrate.io/tutorials/v3/private-network/

实现目标

这里我们学习:

  1. 如何基于Substrate来构成一个两节点的链网络。
  2. 如何配置使用Aura的共识机制。
  3. 如何定制账户,并设置其为Aura的Validator。

启动两个节点的链网络

确认环境准备好了

  1. Rust及相关Rust的工具链已安装。
  2. Substrate node template源码已下载好,且编译通过。
  3. Subkey已安装好(它的安装步骤将在“自主生成key”部分详细讲)。

基于Substrate节点模板启动两节点的链网络

这里,我们将基于节点模板里缺省有的两个账户Alice和Bob,来启动两个Substrate节点,并让这个两个节点相互连接,形成一个链网络。因此,经过这部分学习后,我们应掌握基于Substrate构建多节点链网络的基本步骤。

基于Alice启动Substrate节点

  1. 执行以下的命令,清除之前节点启动可能残留的数据
./target/release/node-template purge-chain --base-path /tmp/alice --chain local

该命令会提示,敲入y

Are you sure to remove "/tmp/alice/chains/local_testnet/db/full"? [y/N]

注:如果希望新建的链是纯净的,就应清除之前启动过的链的数据。

  1. 执行以下的命令,用alice这个账户来启动一个substrate节点。
./target/release/node-template \
--base-path /tmp/alice \
--chain local \
--alice \
--port 30333 \
--ws-port 9945 \
--rpc-port 9933 \
--node-key 0000000000000000000000000000000000000000000000000000000000000001 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator

下面是该命令用到的选项的含义:

:Option :Description
--base-path Specifies the directory for storing all of the data related to this chain.
--chain local Specifies the chain specification to use. Valid predefined chain specifications include local, development, and staging.
--alice Adds the predefined keys for the alice account to the node’s keystore. With this setting, the alice account is used for block production and finalization.
--port 30333 Specifies the port to listen on for peer-to-peer (p2p) traffic. Because this tutorial uses two nodes running on the same physical computer to simulate a network, you must explicitly specify a different port for at least one account.
--ws-port 9945 Specifies the port to listen on for incoming WebSocket traffic. The default port is 9944. This tutorial uses a custom web socket port number (9945).
--rpc-port 9933 Specifies the port to listen on for incoming RPC traffic. The default port is 9933.
--node-key Specifies the Ed25519 secret key to use for libp2p networking. You should only use this option for development and testing.
--telemetry-url Specifies where to send telemetry data. For this tutorial, you can send telemetry data to a server hosted by Parity that is available for anyone to use.
--validator Specifies that this node participates in block production and finalization for the network.

如果想更详细地了解这些选项,可以输入以下的命令

./target/release/node-template --help
  1. 我们查看节点输出信息,以确认该节点是否运行正常:
    Substrate之旅4:基于Substrate私有链的搭建_第1张图片
  • 先关注 Initializing Genesis block/state (state: 0x7384…0308, header-hash: 0xd2dc…3cc2), 它表示节点应完成初始化,而且生成了创世区块,后面再启动节点,并要与该节点,连成一个网络,这里的信息就应一样;
  • 再看 Local node identity is: 12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp 它指定了该节点的唯一ID:
    • 它的值是由上面命令的选项--node-key决定的;
    • 后面Bob节点想要连接这个节点,就会用到这个ID。
  • Idle (0 peers), best: #0 (0xd2dc…3cc2), finalized #0 (0xd2dc…3cc2), ⬇ 0 ⬆ 0, 这个信息中的0 peers表示链网络中没有其它的节点;后面的两个#0则分别表示没有区块产生和确认。
  • 我们还看到报错信息❌ Error while dialing /dns/telemetry.polkadot.io/tcp/443/x-parity-wss/%2Fsubmit%2F: Custom { kind: Other, error: Timeout }, 这是由于连接遥测服务器失败。

这个错误,我们后面再分析。

  1. 浏览器中打开以下网址,以查看节点信息
https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9945#/explorer

会看到以下信息:
Substrate之旅4:基于Substrate私有链的搭建_第2张图片

基于Bob启动Substrate节点

  1. 清除与Bot账户相关的数据。
./target/release/node-template purge-chain --base-path /tmp/bob --chain local -y
  1. 启动关联着账户Bob的第二个Substrate节点:
./target/release/node-template \
--base-path /tmp/bob \
--chain local \
--bob \
--port 30334 \
--ws-port 9946 \
--rpc-port 9934 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator \
--bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp

Substrate之旅4:基于Substrate私有链的搭建_第3张图片
从输出信息来看:

  • 两个节点的peers都是1了,也就是双方都看到了对方,它们俩组成了一个链网络。
  • 另外,整个链网络也出块了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DmixwKtR-1656495046021)(C:\Users\Admin\AppData\Roaming\Typora\typora-user-images\1652081062719.png)]

  1. 几个注意点
  • 命令选项--bootnodes中的ID,应与Alice那个节点一致;
  • 由于我们两个节点是运行在同一台机器上,所以--port --ws-port --rpc-port指定的端口号,应与Alice节点不一样,也应与机器中其它应用占用的端口号不一样。

自主生成key

如果是一条私有链,肯定不能用模板代码里缺省的Alice、Bob、Charly等的账户密钥。所以这个章节里来学习如何为私有定制的链创建自有的账户密钥组。

生成密钥工具准备

生成Substrate的密钥组,有两种方式:

  1. 基于node-template的子命令key来生成。
  2. 通过Subkey命令行程序来生成。

由于Subkey具有密钥生成功能,还有密钥解析等功能。所以这里我们将通过Subkey这个工具来生成Substrate的密钥工具。

  1. 下载paritytech substrate的git仓库
git clone https://github.com/paritytech/substrate.git
cd substrate
  1. 编译出substrate可执行的二进制程序
# Run this in the Substrate working directory
cargo build -p subkey --release

  1. 确认substrate编译成功
# 查看命令帮助
subkey -h

# 查看具体子命令帮助
subkey <sub-command> -h

# 查看版本
subkey --version

在这里插入图片描述

注:上编译生成的二进制可执行文件在./target/release/subkey

  1. 下面则是用subkey来查阅助记词对应的密钥组信息
subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very"

该命令的输出如下:

Secret phrase:       caution juice atom organ advance problem want pledge someone senior holiday very
  Network ID:        substrate
  Secret seed:       0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849
  Public key (hex):  0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746
  Account ID:        0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746
  Public key (SS58): 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR
  SS58 Address:      5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR

  1. 下面则是用subkey来查阅密钥种子对应的密钥信息
subkey inspect 0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849

该命令的输出是:

Secret Key URI `0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849` is account:
  Network ID:        substrate 
 Secret seed:       0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849
  Public key (hex):  0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746
  Account ID:        0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746
  Public key (SS58): 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR
  SS58 Address:      5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR

  1. 这里顺便讲讲密钥的两种格式
  • 纯十六进制;
  • ss58编码格式。

密钥生成

  1. 生成sr25519密钥
subkey generate

该命令的输出:

Secret phrase:       cheese member coin boring actual vehicle mountain obtain obey expect together chat
  Network ID:        substrate
  Secret seed:       0xacc29d509e2ccbdc2e3e6e40f7793c2186133b0f50a5b90de3fa4c8f12b8e7ba
  Public key (hex):  0x90917068a441d2ea0e1aed40fb30d57d290efe705e937ef2c52f3bfb82aa3e4f
  Account ID:        0x90917068a441d2ea0e1aed40fb30d57d290efe705e937ef2c52f3bfb82aa3e4f
  Public key (SS58): 5FLFxTafwbAHxBmKs1pS3MVcfFFDo9N3Vpo23eGzddxS6itx
  SS58 Address:      5FLFxTafwbAHxBmKs1pS3MVcfFFDo9N3Vpo23eGzddxS6itx

该命令缺省用的助记词是12个。为了安全,可以用选项--word 24来选择用24个助记词。除了12与24这两个参数,还支持15、18、21。

  1. 生成ed25519密钥
subkey generate --scheme ed25519

这里使用了--scheme来指定所用的密钥格式。

该命令的输出:

Secret phrase:       enact acoustic logic soap witness hurt knee web gravity bid hawk project
  Network ID:        substrate
  Secret seed:       0xa30dd474ade0684aa08f6cf28370613c193d92a1215b98a6ed0248dbe60d68f5
  Public key (hex):  0xdf12dc2da06e364c6bfe6bac80afe74356e9784d10ad1d72df41183c5b7aa5df
  Account ID:        0xdf12dc2da06e364c6bfe6bac80afe74356e9784d10ad1d72df41183c5b7aa5df
  Public key (SS58): 5H7C8xgztQ5AyiXN36LXMygcy7AcAsUbrkY9AAbcF4R6p8JJ
  SS58 Address:      5H7C8xgztQ5AyiXN36LXMygcy7AcAsUbrkY9AAbcF4R6p8JJ

  1. 下面是关于输出信息的解释
  • Secret phrase,助记词。
  • Secret seed,私钥,可以通过它来恢复公、私钥对。
  • Public key (hex),公钥,十六机制格式。
  • Account ID,十六机制公钥的别名。
  • SS58 Address,与公钥绑定的基于SS58格式的地址。
  1. Substrate为一个账户创建密钥,要同时创建两对
  • Sr25519密钥对,用于aura共识;
  • Ed25519密钥对,用于GRANDPA共识;
  • 创建Ed25519密钥对,应当使用前面Sr25519密钥对产生的助记词,以确保两对密钥对,是授予同一个账户。
  1. 为了组建私有定制的链网络,我们应该按照上面的命令,至少为两个账户生成密钥

定制私有链规格(Spec)

一条链区别与其它的链,关键在于创世区块不同。而创世区块的生成,又依赖于链的Spec配置。因此,这里将讲讲基于Substrate,链的Spec获取与定制。

在这个Spec定制中,我们将使用上面生成的两个密钥组,以便两组密钥账户成为该私有链的Validators。

获得链Spec

执行以下的命令,将模板节点local链的Spec,导致指定文件customSpec.json

./target/release/node-template build-spec --disable-default-bootnode --chain local > customSpec.json

修改链Spec

下面就是基于上面导出的Spec文件customSpec.json,进行修改。

  1. 修改Spec里的name配置为下面的内容。
"name": "My Custom Testnet",

  1. 用前面生成的两个Sr25519 SS58地址更换aura域的对应地址。
  2. 用前面生成的两个Ed25519 SS58地址更换grandpa域的对应地址。
  • 我们看到grandpa域里,除了地址值,还有个数字,它用来设定该账户的投票权重。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5BUHIMKa-1656495046023)(C:\Users\Admin\AppData\Roaming\Typora\typora-user-images\1652170469802.png)]

  1. 将上面编辑好的Spec文件``,转换成Raw格式,以便运行的节点,可以访问。
./target/release/node-template build-spec --chain=customSpec.json --raw --disable-default-bootnode > customSpecRaw.json

  1. 将生成好的Raw格式的Spec文件,分发给需要连入同一私有链的同事。

启动私有链

这里则讲讲如何使用定制的链Spec业启动这条具体的链。

  1. 执行以下的命令,启动引导节点(bootnode)
./target/release/node-template \
--base-path /tmp/node01 \
--chain ./customSpecRaw.json \
--port 30333 \
--ws-port 9945 \
--rpc-port 9933 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator \
--rpc-methods Unsafe \
--name MyNode01

下面是上面命令,几个选项的含义:

  • –base-path,指定了该节点的工作运行时的工作目录;
  • –chain,指定该节点启动所遵循的Spec
  • –rpc-methods Unsafe,表明该节点是测试用,允许使用非安全的通信模式
  • –name,为该节点起了一个名字
  1. 查看bootnode启动的信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MOOkKyzh-1656495046024)(C:\Users\Admin\AppData\Roaming\Typora\typora-user-images\1652171979593.png)]

  • 可以看到该节点的创世区块的Hash与缺省模板节点不一样;
  • 同样,请记下该节点的ID:12D3KooWLkg3xZFTf6YEyonVjQheBWQgFJ6x29bpKuJJYb5ysWFv
  1. 执行以下的命令,以将一个aura的密钥,存放到keystore,以便对aura共识签名
./target/release/node-template key insert --base-path /tmp/node01 \
--chain customSpecRaw.json \
--scheme Sr25519 \
--suri <your-secret-seed> \
--password-interactive \
--key-type aura

  • 其中,应替换为你生成一个密钥对时的助记词,或密码种子。
  1. 执行以下的命令,将与上面同用户的grandpa密钥插入keystore,以便对grandpa共识进行签名
./target/release/node-template key insert --base-path /tmp/node01 \
--chain customSpecRaw.json \
--scheme Ed25519 \
--suri <your-secret-key> \
--password-interactive \
--key-type gran

其中,应替换为你生成一个密钥对时的助记词,或密码种子。

  1. 通过以下的命令,可以查阅keystore的变化
ls /tmp/node01/chains/local_testnet/keystore

该命令将输出如下

617572611441ddcb22724420b87ee295c6d47c5adff0ce598c87d3c749b776ba9a647f04
6772616e1441ddcb22724420b87ee295c6d47c5adff0ce598c87d3c749b776ba9a647f04

  1. 下面是启动其它节点来与bootnode组建成一个私有链。
  • 执行以下命令启动第二个节点
./target/release/node-template \
--base-path /tmp/node02 \
--chain ./customSpecRaw.json \
--port 30334 \
--ws-port 9946 \
--rpc-port 9934 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator \
--rpc-methods Unsafe \
--name MyNode02 \
--bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWLkg3xZFTf6YEyonVjQheBWQgFJ6x29bpKuJJYb5ysWFv \
--password-interactive

  • 为这个节点添加aura和grandpa的密钥对
  • 重启这个节点。

碰到的问题

访问telemetry.polkadot.io报错

这主要是网络所致。所以请通过以下几步,来确保网络通畅:

  1. 防火墙:如果是调试机器,不妨把防火墙关闭。
  2. 在启动节点的命令里加上以下两个选项:
  • –unsafe-rpc-external
  • –unsafe-ws-external

由于我们的节点是本地定制开发的,可能存在不安全的情形。因此就通过这两个选项,告诉远端服务器本地节点的相应接口调用,可能存在不安全的情形。

我这边确认上面步后,也许由于网络本身的问题,可能会存在超时的问题,但总体的工作正常。

报文件描述符limit太低

按告警提示,执行以下命令,将Ubuntu的最大打开文件数,设置为10000。

ulimit -SHn 10000

执行完命令,不妨再执行以下的命令查验一下

ulimit -n

你可能感兴趣的:(区块链网络系统,rust,区块链,智能合约,去中心化)