创建Substrate 私有网络

article/2025/8/26 8:01:36

创建Substrate 私有网络

所有区块链都要求网络中的节点就消息集及其顺序达成一致,以成功创建区块并从一个区块推进到下一个区块。每个块代表特定时间点的数据状态,节点对状态的一致称为共识。有几种不同的算法用于达成共识,包括:

  • 工作量证明共识取决于验证者节点为将有效块添加到链中所做的计算工作。
  • 权益证明共识选择验证者根据他们锁定为网络中的权益的加密货币持有量将有效块添加到链中。
  • 权威共识证明依赖于一组经批准的账户身份来充当验证者。与已批准账户关联的节点有权将交易放入区块中。

Substrate 节点模板使用权威证明共识模型,也称为权威轮Aura共识。Aura 共识协议将区块生产限制在以循环方式创建区块的授权账户(权威机构)的轮换列表中。

在此之前需要完成:

  • 通过安装Rust 和 Rust 工具链,您已经为 Substrate 开发配置了环境。

  • 您已完成创建您的第一个 Substrate 区块链并在本地安装了 Substrate 节点模板。

  • 您通常熟悉软件开发和使用命令行界面。

  • 您通常熟悉区块链和智能合约平台。

使用预定义账户启动区块链

在生成密钥以启动您自己的私有 Substrate 网络之前,您可以使用预定义的网络规范学习基本原理,该规范称为local并在预定义的用户帐户下运行。

alice本教程的这一部分通过使用名为和的预定义帐户在一台本地计算机上运行两个 Substrate 节点来模拟专用网络bob

启动第一个区块链节点

启动区块链:

  1. 在您的计算机上打开终端外壳。

  2. 切换到编译 Substrate 节点模板的根目录。

  3. 通过运行以下命令清除旧链数据:

    ./target/release/node-template purge-chain --base-path /tmp/alice --chain local
    

    该命令会提示您确认操作:

    Are you sure to remove "/tmp/alice/chains/local_testnet/db"? [y/N]:
    
  4. 键入y以确认您要删除链数据。

    启动新网络时,您应该始终删除旧的链数据。

  5. 通过运行以下命令,使用 alice 帐户启动本地区块链节点:

    ./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-pathSpecifies the directory for storing all of the data related to this chain.
--chain localSpecifies the chain specification to use. Valid predefined chain specifications include local, development, and staging.
--aliceAdds 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 30333Specifies 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 9945Specifies 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 9933Specifies the port to listen on for incoming RPC traffic. The default port is 9933.
--node-key <key>Specifies the Ed25519 secret key to use for libp2p networking. You should only use this option for development and testing.
--telemetry-urlSpecifies 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.
--validatorSpecifies that this node participates in block production and finalization for the network.

有关可用于节点模板的命令行选项的更多信息,请通过运行以下命令查看使用帮助:

./target/release/node-template --help

查看显示的节点消息

如果节点成功启动,终端会显示描述网络操作的消息。例如,您应该看到类似于以下的输出:

2021-03-10 17:34:27  Substrate Node
2021-03-10 17:34:27  ✌️  version 3.0.0-1c5b984-x86_64-linux-gnu
2021-03-10 17:34:27  ❤️  by Substrate DevHub <https://github.com/substrate-developer-hub>, 2017-2021
2021-03-10 17:34:27  📋 Chain specification: Local Testnet
2021-03-10 17:34:27  🏷 Node name: Alice
2021-03-10 17:34:27  👤 Role: AUTHORITY
2021-03-10 17:34:27  💾 Database: RocksDb at /tmp/alice/chains/local_testnet/db
2021-03-10 17:34:27  ⛓  Native runtime: node-template-100 (node-template-1.tx1.au1)
2021-03-10 17:34:27  🔨 Initializing Genesis block/state (state: 0xea47…9ba8, header-hash: 0x9d07…7cce)
2021-03-10 17:34:27  👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
2021-03-10 17:34:27  ⏱  Loaded block-time = 6000 milliseconds from genesis on first-launch
2021-03-10 17:34:27  Using default protocol ID "sup" because none is configured in the chain specs
2021-03-10 17:34:27  🏷 Local node identity is: 12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp
2021-03-10 17:34:27  📦 Highest known block at #0
2021-03-10 17:34:27  〽️ Prometheus server started at 127.0.0.1:9615
2021-03-10 17:34:27  Listening for new connections on 127.0.0.1:9945.
2021-03-10 17:34:32  💤 Idle (0 peers), best: #0 (0x9d07…7cce), finalized #0 (0x9d07…7cce), ⬇ 0 ⬆ 0
2021-03-10 17:34:37  💤 Idle (0 peers), best: #0 (0x9d07…7cce), finalized #0 (0x9d07…7cce), ⬇ 0 ⬆ 0
...

特别是,您应该注意输出中的以下消息:

  • 🔨 Initializing Genesis block/state (state: 0xea47…9ba8, header-hash: 0x9d07…7cce)标识节点正在使用的初始块或**创世块。**当您启动下一个节点时,请验证这些值是否相同。
  • 🏷 Local node identity is: 12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp指定唯一标识此节点的字符串。此字符串由--node-key用于使用alice帐户启动节点的 确定。当您启动第二个节点时,您可以使用此字符串来标识要连接的节点。
  • 2021-03-10 17:34:37 💤 Idle (0 peers), best: #0 (0x9d07…7cce), finalized #0 (0x9d07…7cce), ⬇ 0 ⬆ 0表示网络中没有其他节点并且没有块正在生成。另一个节点必须加入网络,然后才能开始产生块。

附加前端以查看有关节点的信息

通过查看它在终端中产生的输出,您可以看到很多关于节点操作的信息。您还可以通过使用 Web 浏览器访问 Polkadot-JS 图形用户界面来查看有关节点操作的信息。

使用 Polkadot-JS 应用查看节点操作:

  1. 打开网络浏览器。
  2. 导航到 Polkadot-JS 浏览器.

Polkadot-JS Explorer 链接使用rpcURL 参数连接到本地节点。

某些浏览器具有阻止连接到本地节点的广告拦截功能。如果您无法连接到本地节点,请查看您是否启用了广告拦截,并根据需要禁用它。如果您的浏览器阻止连接到本地节点,请尝试使用其他浏览器,例如 Chromium 或下载并托管Polkadot-JS 应用本地。

  1. 单击 Polkadot-JS Explorer 页面左上角显示的网络图标。

显示网络列表

在可用网络列表中展开开发

显示开发网络

验证自定义端点设置为您的本地主机和您为传入 WebSocket 流量指定的端口号。

您可以使用 Polkadot-JS 应用程序的单个实例连接到不同的网络、节点和端点。

自定义端点

您现在应该会在 Polkadot-JS Explorer网络页面中看到类似的内容。

Polkadot-JS 中没有显示块

向区块链网络添加第二个节点

现在您开始使用alice帐户密钥的节点正在运行,您可以使用该bob帐户将另一个节点添加到网络中。因为您要加入一个已经在运行的网络,所以您可以使用正在运行的节点来识别新节点要加入的网络。这些命令与您之前使用的命令相似,但有一些重要区别。

要将节点添加到正在运行的区块链:

  1. 在您的计算机上打开一个的终端外壳。

  2. 切换到编译 Substrate 节点模板的根目录。

  3. 通过运行以下命令清除旧链数据:

    ./target/release/node-template purge-chain --base-path /tmp/bob --chain local -y
    

    通过添加-y到命令中,您可以在不提示您确认操作的情况下删除链数据。

  4. bob通过运行以下命令,使用该帐户启动第二个本地区块链节点:

    ./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
    

    请注意此命令与上一个命令之间的以下差异:

    • 由于这两个节点在同一台物理计算机上运行,因此您必须为--base-path--port--ws-port--rpc-port选项指定不同的值。
    • 此命令包含该--bootnodes选项并指定单个引导节点,该节点由alice.

    --bootnodes选项指定以下信息:

    • ip4表示节点的 IP 地址使用 IPv4 格式
    • 127.0.0.1指定运行节点的 IP 地址。在这种情况下,为localhost.
    • tcp将 TCP 指定为用于对等通信的协议。
    • 30333指定用于对等通信的端口号。在这种情况下,TCP 流量的端口号。
    • 12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp标识此网络要与之通信的运行节点。在这种情况下,节点的标识符开始使用该alice帐户。

验证块已生成并最终确定

启动第二个节点后,节点应作为对等节点相互连接并开始生成块。

验证区块是否被敲定:

  1. 验证您是否在启动第一个节点的终端中看到类似于以下内容的行:

    ...
    2021-03-10 17:47:32  🔍 Discovered new external address for our node: /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp
    2021-03-10 17:47:32  🔍 Discovered new external address for our node: /ip4/<your computer's LAN IP>/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp
    2021-03-10 17:47:33  💤 Idle (1 peers), best: #0 (0x9d07…7cce), finalized #0 (0x9d07…7cce), ⬇ 1.0kiB/s ⬆ 1.0kiB/s
    2021-03-10 17:47:36  🙌 Starting consensus session on top of parent 0x9d07d1757a9ca248e58141ce52a11fca37f71007dec16650b87a853f0d4c7cce
    2021-03-10 17:47:36  🎁 Prepared block for proposing at 1 [hash: 0x727826a5e6fba9a13af11422d4677b5f0743cc733c382232328e69fd307d1d2f; parent_hash: 0x9d07…7cce; extrinsics (1): [0x768a…a9e2]]
    2021-03-10 17:47:36  🔖 Pre-sealed block for proposal at 1. Hash now 0x4841d8b2e62483fa4702b3ddcd1b603803842374dcdc1e9533ad407708b33dd8, previously 0x727826a5e6fba9a13af11422d4677b5f0743cc733c382232328e69fd307d1d2f.
    2021-03-10 17:47:36  ✨ Imported #1 (0x4841…3dd8)
    2021-03-10 17:47:36  ✨ Imported #1 (0xb241…2ae8)
    2021-03-10 17:47:38  💤 Idle (1 peers), best: #1 (0x4841…3dd8), finalized #0 (0x9d07…7cce), ⬇ 0.8kiB/s ⬆ 0.8kiB/s
    2021-03-10 17:47:42  ♻️  Reorg on #1,0x4841…3dd8 to #2,0x8b6a…dce6, common ancestor #0,0x9d07…7cce
    2021-03-10 17:47:42  ✨ Imported #2 (0x8b6a…dce6)
    2021-03-10 17:47:43  💤 Idle (1 peers), best: #2 (0x8b6a…dce6), finalized #0 (0x9d07…7cce), ⬇ 0.8kiB/s ⬆ 0.7kiB/s
    2021-03-10 17:47:48  🙌 Starting consensus session on top of parent 0x8b6a3ab2fe9891b1af008ea0d92dae9bc84cfa5578231e81066d47928822dce6
    2021-03-10 17:47:48  🎁 Prepared block for proposing at 3 [hash: 0xb887aef2097eff5869e38ccec0302bce372ad05ac2cdf9cc4725c38ec071fb7a; parent_hash: 0x8b6a…dce6; extrinsics (1): [0x82ac…2f20]]
    2021-03-10 17:47:48  🔖 Pre-sealed block for proposal at 3. Hash now 0x34d608dd8be6b82bef4a7aaae1ec80930a5c4b8cf9bdc99013410e91544f3a2a, previously 0xb887aef2097eff5869e38ccec0302bce372ad05ac2cdf9cc4725c38ec071fb7a.
    2021-03-10 17:47:48  ✨ Imported #3 (0x34d6…3a2a)
    2021-03-10 17:47:48  💤 Idle (1 peers), best: #3 (0x34d6…3a2a), finalized #0 (0x9d07…7cce), ⬇ 0.7kiB/s ⬆ 0.8kiB/s
    2021-03-10 17:47:53  💤 Idle (1 peers), best: #3 (0x34d6…3a2a), finalized #1 (0xb241…2ae8), ⬇ 0.6kiB/s ⬆ 0.7kiB/s
    2021-03-10 17:47:54  ✨ Imported #4 (0x2b8a…fdc4)
    2021-03-10 17:47:58  💤 Idle (1 peers), best: #4 (0x2b8a…fdc4), finalized #2 (0x8b6a…dce6), ⬇ 0.7kiB/s ⬆ 0.6kiB/s
    ...
    

    这些行表明,由 开始的第一个节点alice有一个对等节点(1 peers),它们已经产生了一些块(best: #4 (0x2b8a…fdc4)),并且这些块正在完成(finalized #2 (0x8b6a…dce6))。

  2. 验证您在启动第二个节点的终端中是否看到类似的输出。

  3. 打开Polkadot-JS 浏览器验证网络正在生产和完成区块。

    块被生产并最终确定

  4. 在每个终端外壳中按 Control-c 关闭两个节点。

生成自己的密钥

现在您知道如何使用命令行选项启动和连接正在运行的节点作为对等节点,您可以生成自己的密钥,而不是使用预定义的帐户密钥。重要的是要记住,区块链网络中的每个参与者都负责生成唯一的密钥。

密钥生成选项

有几种方法可以生成密钥。例如,您可以使用node-template子命令、独立的Subkey命令行程序、Polkadot-JS 应用程序或第三方密钥生成实用程序来生成密钥对。

尽管您可以使用预定义的密钥对来完成本教程,但您永远不会在生产环境中使用这些密钥。本教程不使用预定义的密钥或更安全的subkey程序,而是说明如何使用 Substrate 节点模板和key子命令在本地生成密钥。

使用节点模板生成本地密钥

您已经使用了一些命令行选项来使用预定义alicebob帐户启动本地区块链节点。您还可以使用命令行选项生成随机密钥以与 Substrate 一起使用。

对于本教程,您可以保持连接到 Internet 并使用本地节点生成密钥。作为最佳实践,当您为生产区块链生成密钥时,您应该使用从未连接到互联网的气隙计算机。在生成要在公共区块链上使用的任何密钥之前,您至少应该断开互联网连接。

要使用节点模板生成密钥:

  1. 在您的计算机上打开终端外壳。

  2. 切换到编译 Substrate 节点模板的根目录。

  3. 通过运行以下命令生成随机密钥短语和密钥:

    ./target/release/node-template key generate --scheme Sr25519 --password-interactive
    
  4. 为生成的密钥键入密码。

    该命令生成密钥并显示类似于以下内容的输出:

    Secret phrase:  pig giraffe ceiling enter weird liar orange decline behind total despair fly
    Secret seed:       0x0087016ebbdcf03d1b7b2ad9a958e14a43f2351cd42f2f0a973771b90fb0112f
    Public key (hex):  0x1a4cc824f6585859851f818e71ac63cf6fdc81018189809814677b2a4699cf45
    Account ID:        0x1a4cc824f6585859851f818e71ac63cf6fdc81018189809814677b2a4699cf45
    Public key (SS58): 5CfBuoHDvZ4fd8jkLQicNL8tgjnK8pVG9AiuJrsNrRAx6CNW
    SS58 Address:      5CfBuoHDvZ4fd8jkLQicNL8tgjnK8pVG9AiuJrsNrRAx6CNW
    

    aura您现在拥有用于生成用于一个节点的块的 Sr25519 密钥。在此示例中,帐户的 Sr25519 公钥为:

    5CfBuoHDvZ4fd8jkLQicNL8tgjnK8pVG9AiuJrsNrRAx6CNW

  5. 使用您刚刚生成的帐户的密码短语使用 Ed25519 签名方案派生密钥。

    例如,运行类似于以下的命令:

    ./target/release/node-template key inspect --password-interactive --scheme Ed25519 "pig giraffe ceiling enter weird liar orange decline behind total despair fly"
    
  6. 键入您用于生成的密钥的密码。

    该命令显示类似于以下内容的输出:

    Secret phrase `pig giraffe ceiling enter weird liar orange decline behind total despair fly` is account:
    Secret seed:       0x0087016ebbdcf03d1b7b2ad9a958e14a43f2351cd42f2f0a973771b90fb0112f
    Public key (hex):  0x2577ba03f47cdbea161851d737e41200e471cd7a31a5c88242a527837efc1e7b
    Public key (SS58): 5CuqCGfwqhjGzSqz5mnq36tMe651mU9Ji8xQ4JRuUTvPcjVN
    Account ID:        0x2577ba03f47cdbea161851d737e41200e471cd7a31a5c88242a527837efc1e7b
    SS58 Address:      5CuqCGfwqhjGzSqz5mnq36tMe651mU9Ji8xQ4JRuUTvPcjVN
    

    您现在拥有 Ed25519 密钥,用于完成grandpa用于一个节点的块。在此示例中,该帐户的 Ed25519 公钥为:

    5CuqCGfwqhjGzSqz5mnq36tMe651mU9Ji8xQ4JRuUTvPcjVN

生成第二组密钥

对于本教程,专用网络仅包含两个节点,因此您需要两组密钥。您有几个选项可以继续本教程:

  • 您可以将密钥用于一个或两个预定义帐户。
  • 您可以使用本地计算机上的不同身份重复上一节中的步骤,以生成第二个密钥对。
  • 您可以派生一个子密钥对来模拟本地计算机上的第二个身份。
  • 您可以招募其他参与者来生成加入您的私有网络所需的密钥。

出于说明目的,本教程中使用的第二组键是:

  • Sr25519:5EJPj83tJuJtTVE2v7B9ehfM7jNT44CBFaPWicvBwYyUKBS6 用于aura.
  • Ed25519:5FeJQsfmbbJLTH1pvehBxrZrT5kHvJFj84ZaY5LK7NU87gZS 为grandpa.

创建自定义链规范

生成用于区块链的密钥后,您就可以使用这些密钥对创建自定义链规范,然后与称为****验证器的受信任网络参与者共享您的自定义链规范。

为了使其他人能够参与您的区块链网络,您应该确保他们生成自己的密钥。如果其他参与者已经生成了他们的密钥对,您可以创建自定义链规范来替换local您之前使用的链规范。

本教程说明了如何创建一个两节点网络。您可以按照相同的步骤将更多节点添加到您的网络。

修改现有链规范

以前,您使用命令行选项使用预定义的local链规范将节点添加到区块链。--chain local无需编写全新的链规范,您可以修改之前使用的规范。

要基于现有规范创建新的链规范:

  1. 在您的计算机上打开终端外壳。

  2. 切换到编译 Substrate 节点模板的根目录。

  3. 将本地链规范导出到customSpec.json通过运行以下命令命名的文件:

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

    如果您customSpec.json在文本编辑器中打开该文件,您会看到它包含多个字段,包括一个包含您使用该cargo build --release命令构建的运行时的 Wasm 二进制文件的大 blob。您可以预览第一行和最后几行以查看需要更改的字段,而不是查看整个文件。

  4. customSpec.json通过运行以下命令预览文件中的前几个字段:

    head customSpec.json
    

    该命令显示文件中的第一个字段。例如:

    {"name": "Local Testnet","id": "local_testnet","chainType": "Local","bootNodes": [],"telemetryEndpoints": null,"protocolId": null,"properties": null,"consensusEngine": null,"codeSubstitutes": {},
    
  5. customSpec.json通过运行以下命令预览文件中的最后一个字段:

    tail -n 80 customSpec.json
    

    此命令显示 Wasm 二进制字段后面的最后部分,包括运行时中使用的几个托盘的详细信息,例如sudobalances托盘。

  6. customSpec.json在文本编辑器中打开文件。

  7. 修改该name字段以将此链规范标识为自定义链规范。

    例如:

    "name": "My Custom Testnet",
    
  8. 修改aura字段以通过为每个网络参与者添加 Sr25519 SS58 地址密钥来指定有权创建块的节点。

    "aura": {"authorities": ["5CfBuoHDvZ4fd8jkLQicNL8tgjnK8pVG9AiuJrsNrRAx6CNW","5EJPj83tJuJtTVE2v7B9ehfM7jNT44CBFaPWicvBwYyUKBS6"]},
    
  9. 修改该grandpa字段以通过为每个网络参与者添加 Ed25519 SS58 地址密钥来指定有权完成区块的节点。

    "grandpa": {"authorities": [["5CuqCGfwqhjGzSqz5mnq36tMe651mU9Ji8xQ4JRuUTvPcjVN",1],["5FeJQsfmbbJLTH1pvehBxrZrT5kHvJFj84ZaY5LK7NU87gZS",1]]},
    

    authorities请注意,该部分中的字段有两个数据值grandpa。第一个值是地址键。第二个值用于支持加权投票。在此示例中,每个验证者的权重为1票。

  10. 保存更改并关闭文件。

添加验证器

如您所见,您可以通过修改auragrandpa部分来添加和更改链规范中的权限地址。您可以使用此技术添加任意数量的验证器。

添加验证器:

  • 修改该aura部分以包括Sr25519地址。
  • 修改该grandpa部分以包含Ed25519地址和投票权重。

确保为每个验证器使用唯一的密钥。如果两个验证器具有相同的密钥,它们会产生冲突的块。

有关使用密钥对和签名的更多信息,请参阅公钥加密。

将链规范转换为使用原始格式

准备好包含您要使用的信息的链式规范后,您必须先将其转换为原始规范,然后才能使用它。原始链规范包含与未转换规范相同的信息。但是,原始链规范还包含编码的存储密钥,节点用于引用其本地存储中的数据。分发原始链规范可确保每个节点使用正确的存储密钥存储数据。

要将链规范转换为使用原始格式:

  1. 在您的计算机上打开终端外壳。

  2. 切换到编译 Substrate 节点模板的根目录。

  3. 通过运行以下命令将customSpec.json链规范转换为带有文件名的原始格式:customSpecRaw.json

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

与他人共享链规范

如果您正在创建私有区块链网络以与其他参与者共享,请确保只有一个人创建链规范并与customSpecRaw.json网络中的所有其他验证者共享该规范的最终原始版本(例如文件)。

因为 Rust 编译器生成的优化的 WebAssembly 二进制文件在确定性上无法重现,所以每个生成 Wasm 运行时的人都会生成稍微不同的 Wasm blob。为了确保确定性,区块链网络中的所有参与者必须使用完全相同的原始链规范文件。有关此问题的更多信息,请参阅在我们的 Rust Wasm 构建中寻找一个非确定性错误.

启动专用网络

将自定义链规范分发给所有网络参与者后,您就可以启动自己的私有区块链了。这些步骤类似于您在使用预定义帐户启动区块链中所遵循的步骤。要继续本教程的这一部分,您不再使用单个物理计算机或单个二进制文件。

要继续,请验证以下内容:

  • 您已经为至少两个权限帐户生成或收集了帐户密钥。
  • 您已更新您的自定义链规范,以包含用于块生产 ( aura) 和块完成 ( grandpa) 的密钥。
  • 您已将自定义链规范转换为原始格式,并将原始链规范分发给参与私有网络的节点。

如果您已完成这些步骤,您就可以启动私有区块链中的第一个节点了。

启动第一个节点

作为私有区块链网络的第一个参与者,您负责启动第一个节点,称为bootnode

启动第一个节点:

  1. 在您的计算机上打开终端外壳。

  2. 切换到编译 Substrate 节点模板的根目录。

  3. 如果需要,通过运行以下命令清除旧链数据:

    ./target/release/node-template purge-chain --base-path /tmp/node01 --chain local -y
    
  4. 通过运行以下命令,使用自定义链规范启动第一个节点:

    ./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
    

    请注意对您正在运行以启动节点的命令的以下更改:

    • --alice您使用的是自己的密钥,而不是预定义的帐户。您将在单独的步骤中将密钥添加到密钥库。
    • 命令行--chain选项指定自定义链规范。
    • --name命令行选项使您能够在遥测 UI 中为您的节点提供一个人类可读的名称。
    • --rpc-methods Unsafe命令行选项允许您使用不安全的通信模式继续本教程,因为您的区块链未在生产环境中使用。
  5. 验证您是否看到类似于以下内容的输出:

    2021-11-03 15:32:14 Substrate Node
    2021-11-03 15:32:14 ✌️  version 3.0.0-monthly-2021-09+1-bf52814-x86_64-macos
    2021-11-03 15:32:14 ❤️  by Substrate DevHub <https://github.com/substrate-developer-hub>, 2017-2021
    2021-11-03 15:32:14 📋 Chain specification: My Custom Testnet
    2021-11-03 15:32:14 🏷 Node name: MyNode01
    2021-11-03 15:32:14 👤 Role: AUTHORITY
    2021-11-03 15:32:14 💾 Database: RocksDb at /tmp/node01/chains/local_testnet/db
    2021-11-03 15:32:14 ⛓  Native runtime: node-template-100 (node-template-1.tx1.au1)
    2021-11-03 15:32:15 🔨 Initializing Genesis block/state (state: 0x2bde…8f66, header-hash: 0x6c78…37de)
    2021-11-03 15:32:15 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
    2021-11-03 15:32:15 ⏱  Loaded block-time = 6s from block 0x6c78abc724f83285d1487ddcb1f948a2773cb38219c4674f84c727833be737de
    2021-11-03 15:32:15 Using default protocol ID "sup" because none is configured in the chain specs
    2021-11-03 15:32:15 🏷 Local node identity is: 12D3KooWLmrYDLoNTyTYtRdDyZLWDe1paxzxTw5RgjmHLfzW96SX
    2021-11-03 15:32:15 📦 Highest known block at #0
    2021-11-03 15:32:15 〽️ Prometheus exporter started at 127.0.0.1:9615
    2021-11-03 15:32:15 Listening for new connections on 127.0.0.1:9945.
    2021-11-03 15:32:20 💤 Idle (0 peers), best: #0 (0x6c78…37de), finalized #0 (0x6c78…37de), ⬇ 0 ⬆ 0
    

    请注意以下信息:

    • 输出显示使用块哈希初始化的创世块(state: 0x2bde…8f66, header-hash: 0x6c78…37de)
    • 输出指定您的节点的本地节点身份。在此示例中,节点标识为12D3KooWLmrYDLoNTyTYtRdDyZLWDe1paxzxTw5RgjmHLfzW96SX
    • 输出指定用于节点的IP 地址127.0.0.1是本地主机。

    这些值适用于这个特定的教程示例。您的节点的值会有所不同,您必须将节点的值提供给其他网络参与者才能连接到引导节点。

将密钥添加到密钥库

启动第一个节点后,尚未生成任何块。下一步是将两种类型的密钥添加到网络中每个节点的密钥库中。

对于每个节点:

  • 添加aura权限密钥以启用块生产
  • 添加grandpa权限密钥以启用块完成

有几种方法可以将密钥插入密钥库。对于本教程,您可以使用key子命令插入本地生成的密钥。

要将密钥插入密钥库:

  1. 在您的计算机上打开终端外壳。

  2. 切换到编译 Substrate 节点模板的根目录。

  3. 通过运行类似于以下的命令插入aura从子命令生成的密钥:key

    ./target/release/node-template key insert --base-path /tmp/node01 \
    --chain customSpecRaw.json \
    --scheme Sr25519 \
    --suri <your-secret-seed> \
    --password-interactive \
    --key-type aura
    

    替换为您在使用节点模板生成本地密钥<your-secret-seed>中生成的第一个密钥对的密钥短语或密钥种子。在本教程中,秘密短语是,因此命令行选项指定将密钥插入密钥库的字符串。pig giraffe ceiling enter weird liar orange decline behind total despair fly``--suri

    您还可以从指定的文件位置插入密钥。有关可用命令行选项的信息,请运行以下命令:

    ./target/release/node-template key insert --help
    
  4. 通过运行类似于以下的命令插入grandpa从子命令生成的密钥:key

    ./target/release/node-template key insert --base-path /tmp/node01 \
    --chain customSpecRaw.json \
    --scheme Ed25519 \
    --suri <your-secret-key> \
    --password-interactive \
    --key-type gran
    
  5. node01通过运行以下命令验证您的密钥是否在密钥库中:

    ls /tmp/node01/chains/local_testnet/keystore
    

    该命令显示类似于以下内容的输出:

    617572611441ddcb22724420b87ee295c6d47c5adff0ce598c87d3c749b776ba9a647f04
    6772616e1441ddcb22724420b87ee295c6d47c5adff0ce598c87d3c749b776ba9a647f04
    

允许其他参与者加入

您现在可以使用--bootnodes--validator命令行选项允许其他验证者加入网络。

将第二个验证器添加到专用网络:

  1. 在第二台计算机上打开终端外壳。

  2. 切换到编译 Substrate 节点模板的根目录。

  3. 如果需要,通过运行以下命令清除旧链数据:

    ./target/release/node-template purge-chain --base-path /tmp/node02 --chain local -y
    
  4. 通过运行以下命令启动第二个区块链节点:

    ./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/12D3KooWLmrYDLoNTyTYtRdDyZLWDe1paxzxTw5RgjmHLfzW96SX
    

    请务必bootnode在命令中设置正确的标识符。

    如果您没有设置正确的bootnode标识符,您会看到如下错误:

    💔 The bootnode you want to connect to at ... provided a different peer ID than the one you expect: ...

    请注意,该命令包括base-path和命令行选项以及用于指定此节点是专用网络的验证器name的附加选项。validator另请注意,所有验证者必须使用相同的链规范来对等。

  5. 通过运行类似于以下的命令添加aura从子命令生成的密钥:key

    ./target/release/node-template key insert --base-path /tmp/node02 \
    --chain customSpecRaw.json \
    --scheme Sr25519 \
    --suri <second-participant-secret-seed> \
    --password-interactive \
    --key-type aura
    

    替换为您在生成第二个密钥对<second-participant-secret-seed>中生成的密码短语或密码种子。启用区块生产需要密钥类型。aura

  6. 通过运行类似于以下的命令,grandpa将从子命令生成的密钥添加到本地密钥库:key

    ./target/release/node-template key insert --base-path /tmp/node02 \
    --chain customSpecRaw.json \
    --scheme Ed25519 \
    --suri <second-participant-secret-seed> \
    --password-interactive \
    --key-type gran
    

    替换为您在生成第二个密钥对<second-participant-secret-seed>中生成的密码短语或密码种子。启用块最终确定需要密钥类型。gran

    区块最终确定需要至少三分之二的验证者将他们的密钥添加到各自的密钥库中。由于该网络在链规范中配置了两个验证器,因此在第二个节点添加其密钥后开始区块确定。

  7. node02通过运行以下命令验证您的密钥是否在密钥库中:

    ls /tmp/node02/chains/local_testnet/keystore
    

    该命令显示类似于以下内容的输出:

    617572611a4cc824f6585859851f818e71ac63cf6fdc81018189809814677b2a4699cf45
    6772616e1a4cc824f6585859851f818e71ac63cf6fdc81018189809814677b2a4699cf45
    

    Substrate 节点在插入grandpa密钥后需要重新启动,因此您必须在看到区块完成之前关闭并重新启动节点。

  8. 按 Control-c 关闭节点。

  9. 通过运行以下命令重新启动第二个区块链节点:

    ./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/12D3KooWLmrYDLoNTyTYtRdDyZLWDe1paxzxTw5RgjmHLfzW96SX
    

    请注意,该命令包括base-path和命令行选项以及用于指定此节点是专用网络的验证器name的附加选项。validator另请注意,所有验证者必须使用相同的链规范来对等。

    请务必bootnode在命令中设置正确的标识符。如果您没有设置正确的bootnode标识符,您会看到如下错误:

    💔 The bootnode you want to connect to at ... provided a different peer ID than the one you expect: ...

    在两个节点都将其密钥添加到各自的密钥库并重新启动后,您应该会看到相同的创世块和状态根哈希。

    您还应该看到每个节点都有一个对等节点(1 peers),并且它们产生了一个区块提议(best: #2 (0xe111…c084))。几秒钟后,您应该会看到新块正在完成。


http://chatgpt.dhexx.cn/article/aYo3ASuG.shtml

相关文章

Build the Substrate Kitties Chain(中文翻译)

欢迎来到Substrate Kitties课程。 本课程将向您介绍如何构建一个可以创建并持有非同质化代币&#xff08;NFT&#xff0c;这个NFT名称为Substrate Kitties&#xff09;的区块链。课程分为部2部分&#xff1a; Part I 描述如何构建Kitties pallet&#xff0c;以及这个pallet怎样…

oracle substrate,Substrate 2.0 带来了哪些改变?

Substrate 已到了 2.0 版本的主要里程碑处。该区块链框架现在包含链下工作机(off-chain workers)和 70 多个可组合模块&#xff0c;并为构建优化的、与 Polkadot 兼容的、可投入生产的区块链奠定了坚实的基础。数十个实时区块链已经在运行 Substrate 2.0&#xff0c;包括Polkad…

Substrate 基础教程(Tutorials) -- 授权特定节点

五、授权特定节点 在添加可信节点中&#xff0c;您看到了如何使用一组已知的验证器节点构建一个简单的网络。该教程演示了一个简化版的许可网络&#xff08;permissioned network&#xff09;。在一个被许可的网络中&#xff0c;只有被授权的节点&#xff08;authorized nodes…

Substrate常见问题

目录标题 1. Rust nightly not installed, please install it!2. Rust WASM toolchain not installed, please install it!3. use pallet::*出错4. failed to load manifest for workspace member5. error: failed to run custom build command for node-template-runtime v4.0…

什么是 Substrate

如果你关注了 Polkadot 项目&#xff0c;可能会多次看到「Substrate」这个词。 它是 Polkadot 项目的重要组成部分&#xff0c;但有关它的信息非常少。 白皮书或黄皮书里找不到&#xff0c; 至少没有专门的介绍「Substrate」。 从较高的层面来看&#xff0c;Substrate 是一个可…

Substrate之旅3:Substrate是什么

Substrate 是从Polkadot 孵化出来的项目。它是一个用来搭建区块链的通用框架&#xff0c;具有以下特点&#xff1a; 可扩展。模块化。开源。 Substrate的框架与组件 框架 其中&#xff1a; P2P: libp2p网络协议&#xff0c;Substrate基于该协议实现了一个不带任何假设的&…

Substrate 基础 -- 教程(Tutorials)

官网 github DOC 面向未来的区块链框架 Substrate 使开发人员能够快速、轻松地构建适合任何用例的未来 证明区块链(future proof blockchains)。 Substrate 文档包括区块链构建器&#xff08;blockchain builders&#xff09;和parachain 项目团队的概念、过程和参考信息。…

【Android 逆向】substrate 框架 ( substrate 简介 | substrate 相关文档资料 )

文章目录 一、substrate 简介二、substrate 相关文档资料 一、substrate 简介 substrate 官网 : http://www.cydiasubstrate.com substrate 框架 是 Cydia 下的逆向工具 , 该框架是开源的 ; substrate 配合对应的 so 动态库 和 头文件 , 可以在 Android / iOS 平台中独立运行 …

ios tableView那些事(三)给tableView添加些图片

感觉光有数据的tableView很丑&#xff0c;那么我们就来美化下吧&#xff0c;加一些图片 #import <UIKit/UIKit.h> /*tableview 一定要用到这两个delegate UITableViewDataSource,UITableViewDelegate */ interface ViewController :UIViewController <UITableViewDa…

QT的TableView实现多级表头

QT的TableView实现多级表头 最近项目需要支持多级表头&#xff0c;QT本身不支持。可重写QHeaderView表头实现。 demo如下&#xff1a; FSItemDelegate.h #pragma once/* 自定义委托类 */ #include <QItemDelegate> #include <QSpinBox> #include <QDoubleSpin…

QML类型:TableView

一、描述 TableView 显示从内置 QML 类型&#xff08;如 ListModel 和 XmlListModel&#xff09;创建的模型中的数据&#xff0c;这些模型仅填充 TableView 中的第一列。要创建具有多列的模型&#xff0c;请使用 TableModel 或继承 QAbstractItemModel 的 C 模型。 TableView…

QML TableView表格使用示例

前言 QML中实现表格可以使用多种方式&#xff0c;比如直接使用ListView&#xff0c;定义每一行delegate&#xff0c;或者自定义Rectangle&#xff0c;放到Flipable中组合使用。Qt Quick Control1中 从5.1版本开始就提供了表格控件&#xff0c;但是感觉不怎么好用&#xff0c;在…

Qt TableView的简单使用

软件环境&#xff1a; ubuntu -------------------------------------------------------------------------------------------------------- 最终效果图&#xff1a; --------------------------------------------------------------------------------------------------…

PyQt5 TableView组件

一、话不多说&#xff0c;先看图 本次要实现的是主窗口内添加widget组件&#xff0c;widget内设置成垂直盒布局&#xff0c;然后在布局中添加tableView、PushButton组件 二、看main函数 if __name__ __main__:app QApplication(sys.argv)# 现在这创建 主窗口 &#xff08;不然…

优雅的开发TableView

前言 UITableView&#xff08;UITableViewController&#xff09;是iOS开发使用频率最高的一个组件。 不管是使用UITableView还是还是UITableViewController&#xff0c;在开发的时候&#xff0c;我们都需要实现两个协议&#xff1a; UITableViewControllerDataSourceUITabl…

JavaFX控件——TableView

在JavaFX 应用中对创建表格最重要的是TableView, TableColumn和TableCell这三个类。 你可以通过实现数据模型&#xff08;data model&#xff09; 和 实现 单元格工厂(cell factory) 来填充表格。 表格类提供了表格列嵌入式的排序能力和必要时调整列宽度的功能。 下面开始学…

ios开发:多个Section的TableView

开发多个Section的tableView。 首先应该考虑到数据源该如何得到 我们这里可以通过两种方式:第一种是读取plist文件。第二种是通过代码进行数据存储以及读取。 多个Section需要的数据源是一个字典&#xff0c;字典里的内容是一个数组。在plist文件中可以这样去创建 在.h文件中…

tableview概述

转自&#xff1a;http://www.cnblogs.com/smileEvday/archive/2012/06/28/tableView.html                 下面分9个方面进行介绍&#xff1a; 一、UITableView概述 UITableView继承自UIScrollView&#xff0c;可以表现为Plain和Grouped两种风格&#xff0c;分…

ios tableView那些事(一)创建一个简单的tableView

工作也有半年多了&#xff01;几乎每个项目中的会用到tableview这个神奇而好用的控件&#xff0c;在学习和工作中都会看别人的博客&#xff01;对我有很大的帮助&#xff0c;就如同站在巨人的肩膀上的感觉吧 哈哈&#xff01;于是决定重新开始写博客&#xff0c;希望能帮助像我…

JavaFX TableView和ListView的点击事件

项目场景&#xff1a; 最近在用JavaFX做一个简易的商城界面&#xff0c;大概想实现这样的功能&#xff1a; 左边显示用户的最近五个购买的产品 使用ListView 点击ListView的项目会定位到相应的tablerow位置 方便用户快速查找中间显示所有可用产品 使用TableView 双击tablerow…