Substrate 基础教程(Tutorials) -- 授权特定节点
五、授权特定节点
在添加可信节点中,您看到了如何使用一组已知的验证器节点构建一个简单的网络。该教程演示了一个简化版的许可网络(permissioned network)。在一个被许可的网络中,只有被授权的节点(authorized nodes)被允许执行特定的网络活动。例如,您可以授予一些节点验证块的权限,授予其他节点传播交易的权限。
具有被授予特定权限的节点的区块链不同于公共(public )或无授权(permissionless )的区块链。在无授权的区块链中,任何人都可以通过在合适的硬件上运行节点软件来加入网络。一般来说,无授权区块链提供了更大的网络去中心化。但是,在某些用例中,创建一个受许可的区块链可能是合适的。例如,一个被许可的区块链将适用于以下类型的项目:
- 用于私有或联盟网络(private or consortium network),如私人企业或非营利组织。
- 在高度监管的数据环境中,例如医疗保健、金融或企业对企业分类账。
- 用于大规模测试预公开的区块链网络(pre-public blockchain )。
本教程演示如何使用节点授权 pallet构建带有Substrate的受许可网络。
5.1 节点授权和所有权
节点授权 pallet
是一个预先构建的 FRAME
托盘,使您能够管理网络的一组可配置的节点。每个节点由一个peer identifier (PeerId
)标识。每个对等标识符由声明该节点的一个且只有能一个帐户所有者(AccountId
)拥有。
有两种方式可以授权一个节点加入网络:
- 通过将对等标识符添加到链规范文件中的预定义节点列表中,作为链的起源配置的一部分。您必须获得链的治理机制的批准,或者有权访问网络中
Sudo
pallet 的根帐户才能执行此操作。 - 通过请求来自特定节点的配对对等(paired peer )连接。您可以使用预定义的节点对等标识符,或者使用每个节点的公钥和私钥生成的对等标识符,在节点之间添加连接。
如下图所示,本教程演示了两种授权方法,其中Alice和Bob的对等标识符定义在链规范中,其他节点使用节点授权pallet(node authorization pallet
)添加。
请注意,任何用户都可以声称自己是PeerId
的所有者。为了防止错误声明,应该在启动节点之前声明节点标识符。启动节点后,它的PeerID
对网络可见,任何人都可以随后声明它。
作为节点的所有者,您可以为节点添加和删除连接。例如,您可以操作预定义节点与您的节点之间的连接,或者您的节点与其他非预定义节点之间的连接。不能更改预定义节点的连接。他们总是被允许相互联系。
节点授权(node-authorization
)pallet 使用脱链工作器(offchain worker )来配置其节点连接。请确保在启动节点时启用脱链工作器,因为对于非权威节点,默认情况下它是禁用的。
5.2 教程的目标
通过完成本教程,您将实现以下目标:
- 签出并编译节点模板。
- 将节点授权托盘(node authorization pallet)添加到节点模板运行时。
- 启动多个节点并授权新节点加入。
5.3 构建节点模板
参考前面文章
5.4 添加节点授权托盘
在使用新托盘之前,必须将有关它的一些信息添加到编译器用于构建运行时二进制文件的配置文件中。
对于Rust程序,您使用Cargo.toml
文件定义配置设置和依赖项,这些设置和依赖项决定在生成的二进制文件中编译什么。因为Substrate运行时既编译为包含标准库函数的原生Rust二进制文件,也编译为不包含标准库的WebAssembly (Wasm)二进制文件,即Cargo.toml
文件控制两个重要的信息:
- 作为运行时依赖项导入的托盘,包括要导入的托盘的位置和版本。
- 在编译本机Rust二进制文件时,每个托盘中应该启用的特性。通过启用每个托盘的标准(
std
)特性集,您可以将运行时编译为包含函数、类型和原语,否则在构建WebAssembly
二进制时就会丢失这些原语。
有关在Cargo.toml
文件中添加依赖项的一般信息,请参阅Cargo文档中的依赖项。有关启用和管理依赖包中的特性的信息,请参阅Cargo文档中的特性。
5.5 添加节点授权依赖项
将节点授权(node-authorization
)托盘添加到Substrate
运行时:
- 打开终端shell并更改到节点模板的根目录。
- 在文本编辑器中打开
runtime/Cargo.toml
配置文件。 - 找到
[dependencies]
部分,并添加pallet-node-authorization
crate ,使其对节点模板运行时可用。
[dependencies]
pallet-node-authorization = { default-features = false, version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" }
这一行将pallet-node-authorization
crate 作为依赖项导入,并为板条箱指定以下配置细节:
- 在编译运行时时,默认情况下不启用托盘特性。
- crate的版本标识符。
- 检索
pallet-node-authorization
crate 的存储库位置。 - 用来取crate 的分支
请注意,您应该对所有托盘使用相同的分支和版本信息,以确保它们彼此兼容。使用来自不同分支的托盘可能会导致编译器错误。这个示例演示了向Cargo.toml
文件添加托盘,如果其他托盘使用branch = "polkadot-v0.9.28"
。
将pallet-node-authorization/std
特性添加到要在编译运行时启用的features
列表中。
[features]
default = ['std']
std = [..."pallet-node-authorization/std", # add this line...
]
此部分指定此运行时要编译的默认特性集是std
特性集。当使用std
特性集编译运行时,将启用作为依赖项列出的所有托盘中的std
特性。有关如何使用标准库将运行时编译为原生Rust二进制文件,以及如何使用no_std
属性将运行时编译为WebAssembly二进制文件的更多详细信息,请参见构建过程。
如果您忘记更新Cargo.toml
文件中的features
部分,您可能会看到在编译运行时二进制文件时cannot find function
错误。
通过运行以下命令检查新的依赖项是否正确解析:
cargo check -p node-template-runtime --release
5.6 添加管理规则
为了在本教程中模拟治理,您可以配置托盘以使用可以使用Sudo
托盘调用的EnsureRoot
特权函数。默认情况下,节点模板中包含Sudo
托盘,并允许您通过根级管理帐户(root-level administrative account
)进行调用。在生产环境中,您将使用更实际的基于治理的检查。
要在运行时启用EnsureRoot
规则:
- 打开
runtime/src/lib.rs
文件。 - 在文件中添加如下一行:
use frame_system::EnsureRoot;
5.7 实现Config
trait
每个托盘都有一个Rust trait,称为Config
。Config
trait 用于标识托盘所需的参数和类型。
添加托盘所需的大多数特定于托盘的代码都是使用Config
trait实现的。您可以通过参考其Rust文档或该托盘的源代码来查看需要为任何托盘实现的内容。例如,要了解在节点授权托盘中需要为Config
trait 实现什么,可以参考Rust文档中的pallet_node_authorization::Config。
要在运行时中实现node-authorization
托盘:
- 打开
runtime/src/lib.rs
文件。 - 使用以下代码为托盘添加
parameter_types
部分:
parameter_types! {pub const MaxWellKnownNodes: u32 = 8;pub const MaxPeerIdLength: u32 = 128;
}
- 使用以下代码为托盘的
Config
trait添加impl
部分:
impl pallet_node_authorization::Config for Runtime {type RuntimeEvent = RuntimeEvent;type MaxWellKnownNodes = MaxWellKnownNodes;type MaxPeerIdLength = MaxPeerIdLength;type AddOrigin = EnsureRoot<AccountId>;type RemoveOrigin = EnsureRoot<AccountId>;type SwapOrigin = EnsureRoot<AccountId>;type ResetOrigin = EnsureRoot<AccountId>;type WeightInfo = ();
}
- 使用以下代码行将托盘添加到
construct_runtime
宏:
construct_runtime!(
pub enum Runtime whereBlock = Block,NodeBlock = opaque::Block,UncheckedExtrinsic = UncheckedExtrinsic{/*** Add This Line ***/NodeAuthorization: pallet_node_authorization::{Pallet, Call, Storage, Event<T>, Config<T>},}
);
- 执行以下命令检查配置是否可以编译。
cargo check -p node-template-runtime --release
为授权节点添加genesis存储
在启动网络以使用节点授权之前,需要进行一些额外的配置来处理对等标识符和帐户标识符。例如,PeerId
以bs58
格式编码,因此您需要在node/Cargo.toml
中为bs58库添加一个新的依赖项。对PeerId
进行解码,得到PeerId
的bytes。为了简单起见,授权的节点与预定义的帐户相关联。
为授权节点配置genesis存储:
- 打开
node/Cargo.toml
- 找到
[dependencies]
部分并将bs58
库添加到节点模板中。
[dependencies]
bs58 = { version = "0.4.0" }
- 打开
node/src/chain_spec.rs
- 使用以下代码为被授权加入网络的节点添加genesis存储:
use sp_core::OpaquePeerId; // A struct wraps Vec<u8> to represent the node `PeerId`.
use node_template_runtime::NodeAuthorizationConfig; // The genesis config that serves the pallet.
- 找到为FRAME模块配置初始存储状态的
testnet_genesis
函数。
- 在
GenesisConfig
声明中,添加以下代码块:
node_authorization: NodeAuthorizationConfig {nodes: vec![(OpaquePeerId(bs58::decode("12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2").into_vec().unwrap()),endowed_accounts[0].clone()),(OpaquePeerId(bs58::decode("12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust").into_vec().unwrap()),endowed_accounts[1].clone()),],},
在这段代码中,NodeAuthorizationConfig
包含一个nodes
属性,它是一个包含两个元素的元组的向量。元组的第一个元素是OpaquePeerId
。bs58::decode
操作将人类可读的PeerId
(例如,12d3koowbmawcd4pjnjvfv89hwe48nwkrmago8vy3uqeynnhbox2
)转换为字节。元组的第二个元素是AccountId
,表示该节点的所有者。本例使用预定义的Alice和Bob,在这里被标识为赋值帐户[0]和[1]。
验证节点是否编译成功
cargo build --release
如果没有语法错误,就可以继续了。如果有错误,请按照编译输出中的说明修复它们,然后重新运行cargo构建命令。
5.8 标识要使用的帐户密钥
您已经在genesis存储中配置了与Alice和Bob帐户关联的节点。您可以使用 subkey程序检查与预定义帐户相关联的密钥,并生成和检查您自己的密钥。但是,如果您运行subkey generate-node-key
命令,您的节点密钥和对等标识符将随机生成,并且不会与教程中使用的密钥匹配。因为本教程使用预定义帐户和众所周知的节点密钥,所以您可以为每个帐户使用以下密钥。
Alice
Key type | Key value |
---|---|
Node key | c12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a |
Peer identifier generated from the node key | 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 |
Peer identifier decoded to hex | 0x0024080112201ce5f00ef6e89374afb625f1ae4c1546d31234e87e3c3f51a62b91dd6bfa57df |
Bob
Key type | Key value |
---|---|
Node key | 6ce3be907dbcabf20a9a5a60a712b4256a54196000a8ed4050d352bc113f8c58 |
Peer identifier generated from the node key | 12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust |
Peer identifier decoded to hex | 0x002408011220dacde7714d8551f674b8bb4b54239383c76a2b286fa436e93b2b7eb226bf4de7 |
另外两个开发帐户—charlie和dave—没有在genesis配置中定义的众所周知的节点键或对等标识符。为了便于演示,您可以对这些帐户使用以下密钥。
Charlie
Key type | Key value |
---|---|
Node key | a99331ff4f0e0a0434a6263da0a5823ea3afcfffe590c9f3014e6cf620f2b19a |
Peer identifier generated from the node key | 12D3KooWPHWFrfaJzxPnqnAYAoRUyAHHKqACmEycGTVmeVhQYuZN |
Peer identifier decoded to hex | 0x002408011220c81bc1d7057a1511eb9496f056f6f53cdfe0e14c8bd5ffca47c70a8d76c1326d |
Dave
Key type | Key value |
---|---|
Node key | a99331ff4f0e0a0434a6263da0a5823ea3afcfffe590c9f3014e6cf620f2b19a |
Peer identifier generated from the node key | 12D3KooWPHWFrfaJzxPnqnAYAoRUyAHHKqACmEycGTVmeVhQYuZN |
Peer identifier decoded to hex | 0x002408011220c81bc1d7057a1511eb9496f056f6f53cdfe0e14c8bd5ffca47c70a8d76c1326d |
对于本教程,您可以将 node key 复制到文件中,然后使用subkey inspect-node-key
来验证Charlie
和Dave
的对等标识符。例如,将Charlie的节点密钥保存到名为charlie-node-key
的文件中,然后执行如下命令验证peer 标识符
./subkey inspect-node-key --file charlie-node-key
查看Charlie节点的对等体标识符。
12D3KooWJvyP3VJYymTqG7eH4PM5rN4T2agk5cdNCfNymAqwqcvZ
如果您为自己的帐户生成节点密钥,请将节点的对等标识符保存到一个文件中,以便在需要时将其传递给subkey inspect-node-key
或其他命令。
5.9 启动网络节点
现在可以使用预定义帐户的节点密钥和对等标识符启动受许可的网络,并授权其他节点加入。
在本教程中,您将启动四个节点。其中三个节点与预定义的帐户相关联,所有这三个节点都被允许创建和验证块。第四个节点是 sub-node
,它只被授权在节点所有者批准的情况下从选定的节点读取数据。
启动第一个节点
因为您已经配置了genesis存储为Alice和Bob使用众所周知的节点键,您可以使用-name alice --validator
命令的快捷方式--alice
来启动第一个节点。
启动第一个节点:
./target/release/node-template \
--chain=local \
--base-path /tmp/validator1 \
--alice \
--node-key=c12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a \
--port 30333 \
--ws-port 9944 \
--unsafe-ws-external \
--unsafe-rpc-external
[root@localhost substrate-node-template]# ./target/release/node-template --chain=local --base-path /tmp/validator1 --alice --node-key=c12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a --port 30333 --ws-port 9944 --unsafe-ws-external
2023-03-02 17:40:31 Low open file descriptor limit configured for the process. Current value: 4096, recommended value: 10000.
2023-03-02 17:40:31 Substrate Node
2023-03-02 17:40:31 ✌️ version 4.0.0-dev-d79d8cef20b
2023-03-02 17:40:31 ❤️ by Substrate DevHub <https://github.com/substrate-developer-hub>, 2017-2023
2023-03-02 17:40:31 📋 Chain specification: Local Testnet
2023-03-02 17:40:31 🏷 Node name: Alice
2023-03-02 17:40:31 👤 Role: AUTHORITY
2023-03-02 17:40:31 💾 Database: RocksDb at /tmp/validator1/chains/local_testnet/db/full
2023-03-02 17:40:31 ⛓ Native runtime: node-template-100 (node-template-1.tx1.au1)
2023-03-02 17:40:32 🔨 Initializing Genesis block/state (state: 0xabe9…794a, header-hash: 0x1280…bbc0)
2023-03-02 17:40:32 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
2023-03-02 17:40:32 Using default protocol ID "sup" because none is configured in the chain specs
2023-03-02 17:40:32 🏷 Local node identity is: 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2
2023-03-02 17:40:32 💻 Operating system: linux
2023-03-02 17:40:32 💻 CPU architecture: x86_64
2023-03-02 17:40:32 💻 Target environment: gnu
2023-03-02 17:40:32 💻 CPU: Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz
2023-03-02 17:40:32 💻 CPU cores: 2
2023-03-02 17:40:32 💻 Memory: 1960MB
2023-03-02 17:40:32 💻 Kernel: 5.4.230-1.el7.elrepo.x86_64
2023-03-02 17:40:32 💻 Linux distribution: CentOS Linux 7 (Core)
2023-03-02 17:40:32 💻 Virtual machine: yes
2023-03-02 17:40:32 📦 Highest known block at #0
2023-03-02 17:40:32 〽️ Prometheus exporter started at 127.0.0.1:9615
2023-03-02 17:40:32 Running JSON-RPC HTTP server: addr=127.0.0.1:9933, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"]
2023-03-02 17:40:32 Running JSON-RPC WS server: addr=0.0.0.0:9944, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"]
2023-03-02 17:40:37 💤 Idle (0 peers), best: #0 (0x1280…bbc0), finalized #0 (0x1280…bbc0), ⬇ 0 ⬆ 0
在此命令中,使用--node-key
选项指定用于安全连接到网络的密钥。该键也在内部用于生成人类可读的PeerId
,如上面部分所示。
启动第二个节点
您可以使用-name bob--validator
命令的快捷方式--bob
来启动第一个节点。
./target/release/node-template \
--chain=local \
--base-path /tmp/validator2 \
--bob \
--node-key=6ce3be907dbcabf20a9a5a60a712b4256a54196000a8ed4050d352bc113f8c58 \
--bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 \
--port 30334 \
--ws-port 9945 \
--unsafe-ws-external
[root@localhost ~]# cd /home/ycp/work_space/rust_dev/substrate/substrate-node-template/
[root@localhost substrate-node-template]# ./target/release/node-template \
> --chain=local \
> --base-path /tmp/validator2 \
> --bob \
> --node-key=6ce3be907dbcabf20a9a5a60a712b4256a54196000a8ed4050d352bc113f8c58 \
> --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 \
> --port 30334 \
> --ws-port 9945
2023-03-03 13:11:36 Low open file descriptor limit configured for the process. Current value: 4096, recommended value: 10000.
2023-03-03 13:11:36 Substrate Node
2023-03-03 13:11:36 ✌️ version 4.0.0-dev-d79d8cef20b
2023-03-03 13:11:36 ❤️ by Substrate DevHub <https://github.com/substrate-developer-hub>, 2017-2023
2023-03-03 13:11:36 📋 Chain specification: Local Testnet
2023-03-03 13:11:36 🏷 Node name: Bob
2023-03-03 13:11:36 👤 Role: AUTHORITY
2023-03-03 13:11:36 💾 Database: RocksDb at /tmp/validator2/chains/local_testnet/db/full
2023-03-03 13:11:36 ⛓ Native runtime: node-template-100 (node-template-1.tx1.au1)
2023-03-03 13:11:38 🔨 Initializing Genesis block/state (state: 0xabe9…794a, header-hash: 0x1280…bbc0)
2023-03-03 13:11:38 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
2023-03-03 13:11:39 Using default protocol ID "sup" because none is configured in the chain specs
2023-03-03 13:11:39 🏷 Local node identity is: 12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust
2023-03-03 13:11:39 💻 Operating system: linux
2023-03-03 13:11:39 💻 CPU architecture: x86_64
2023-03-03 13:11:39 💻 Target environment: gnu
2023-03-03 13:11:39 💻 CPU: Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz
2023-03-03 13:11:39 💻 CPU cores: 2
2023-03-03 13:11:39 💻 Memory: 1960MB
2023-03-03 13:11:39 💻 Kernel: 5.4.230-1.el7.elrepo.x86_64
2023-03-03 13:11:39 💻 Linux distribution: CentOS Linux 7 (Core)
2023-03-03 13:11:39 💻 Virtual machine: yes
2023-03-03 13:11:39 📦 Highest known block at #0
2023-03-03 13:11:39 Running JSON-RPC HTTP server: addr=127.0.0.1:38501, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"]
2023-03-03 13:11:39 Running JSON-RPC WS server: addr=127.0.0.1:9945, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"]
2023-03-03 13:11:39 discovered: 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 /ip4/172.17.0.1/tcp/30333
2023-03-03 13:11:39 discovered: 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 /ip4/192.168.159.128/tcp/30333
2023-03-03 13:11:39 discovered: 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 /ip4/192.168.122.1/tcp/30333
2023-03-03 13:11:39 discovered: 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 /ip4/172.18.0.1/tcp/30333
2023-03-03 13:11:42 🙌 Starting consensus session on top of parent 0x1280d6cee470b920e522114266a3c6695a25543c01ec95bd72900e4b7f4dbbc0
2023-03-03 13:11:42 🎁 Prepared block for proposing at 1 (0 ms) [hash: 0x7b7742d7cac5e44872580013037888fd869503a3d726ba69d94edd671093778f; parent_hash: 0x1280…bbc0; extrinsics (1): [0x91c2…3fb0]]
2023-03-03 13:11:42 🔖 Pre-sealed block for proposal at 1. Hash now 0xf346b19280be500e9678f74c8afaea98f01c3465c31c04861eb3adba61f79f39, previously 0x7b7742d7cac5e44872580013037888fd869503a3d726ba69d94edd671093778f.
2023-03-03 13:11:42 ✨ Imported #1 (0xf346…9f39)
2023-03-03 13:11:44 💤 Idle (1 peers), best: #1 (0xf346…9f39), finalized #0 (0x1280…bbc0), ⬇ 1.0kiB/s ⬆ 1.1kiB/s
2023-03-03 13:11:48 ✨ Imported #2 (0xae84…8b37)
2023-03-03 13:11:49 💤 Idle (1 peers), best: #2 (0xae84…8b37), finalized #0 (0x1280…bbc0), ⬇ 0.9kiB/s ⬆ 0.8kiB/s
2023-03-03 13:11:54 🙌 Starting consensus session on top of parent 0xae84b118f5904a97ad6e73eeff186c5491bd509a3dbeb327be71fd611ce78b37
2023-03-03 13:11:54 🎁 Prepared block for proposing at 3 (0 ms) [hash: 0xd1905fddbad92c08a068c1d4827781b60836a135019e99aed3e59c9215f37ab5; parent_hash: 0xae84…8b37; extrinsics (1): [0x7c68…1dbc]]
向已知节点列表中添加第三个节点
您可以使用--name charlie
命令启动第三个节点。节点授权托盘使用脱链工作器来配置节点连接。因为第三个节点不是一个众所周知的节点,并且它将网络中的第四个节点配置为只读子节点,所以必须包含命令行选项来启用脱链工作器。
./target/release/node-template \
--chain=local \
--base-path /tmp/validator3 \
--name charlie \
--node-key=3a9d5b35b9fb4c42aafadeca046f6bf56107bd2579687f069b42646684b94d9e \
--port 30335 \
--ws-port=9946 \
--offchain-worker always \
--unsafe-ws-external
[root@localhost substrate-node-template]# ./target/release/node-template \
> --chain=local \
> --base-path /tmp/validator3 \
> --name charlie \
> --node-key=3a9d5b35b9fb4c42aafadeca046f6bf56107bd2579687f069b42646684b94d9e \
> --port 30335 \
> --ws-port=9946 \
> --offchain-worker always \
> --unsafe-ws-external
2023-03-03 13:19:12 Low open file descriptor limit configured for the process. Current value: 4096, recommended value: 10000.
2023-03-03 13:19:12 Substrate Node
2023-03-03 13:19:12 ✌️ version 4.0.0-dev-d79d8cef20b
2023-03-03 13:19:12 ❤️ by Substrate DevHub <https://github.com/substrate-developer-hub>, 2017-2023
2023-03-03 13:19:12 📋 Chain specification: Local Testnet
2023-03-03 13:19:12 🏷 Node name: charlie
2023-03-03 13:19:12 👤 Role: FULL
2023-03-03 13:19:12 💾 Database: RocksDb at /tmp/validator3/chains/local_testnet/db/full
2023-03-03 13:19:12 ⛓ Native runtime: node-template-100 (node-template-1.tx1.au1)
2023-03-03 13:19:14 🔨 Initializing Genesis block/state (state: 0xabe9…794a, header-hash: 0x1280…bbc0)
2023-03-03 13:19:14 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
2023-03-03 13:19:15 Using default protocol ID "sup" because none is configured in the chain specs
2023-03-03 13:19:15 🏷 Local node identity is: 12D3KooWJvyP3VJYymTqG7eH4PM5rN4T2agk5cdNCfNymAqwqcvZ
2023-03-03 13:19:15 💻 Operating system: linux
2023-03-03 13:19:15 💻 CPU architecture: x86_64
2023-03-03 13:19:15 💻 Target environment: gnu
2023-03-03 13:19:15 💻 CPU: Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz
2023-03-03 13:19:15 💻 CPU cores: 2
2023-03-03 13:19:15 💻 Memory: 1960MB
2023-03-03 13:19:15 💻 Kernel: 5.4.230-1.el7.elrepo.x86_64
2023-03-03 13:19:15 💻 Linux distribution: CentOS Linux 7 (Core)
2023-03-03 13:19:15 💻 Virtual machine: yes
2023-03-03 13:19:15 📦 Highest known block at #0
2023-03-03 13:19:15 Running JSON-RPC HTTP server: addr=127.0.0.1:38533, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"]
2023-03-03 13:19:15 Running JSON-RPC WS server: addr=0.0.0.0:9946, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"]
2023-03-03 13:19:15 discovered: 12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust /ip4/172.18.0.1/tcp/30334
2023-03-03 13:19:15 discovered: 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 /ip4/192.168.159.128/tcp/30333
2023-03-03 13:19:15 discovered: 12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust /ip4/192.168.159.128/tcp/30334
2023-03-03 13:19:15 discovered: 12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust /ip4/192.168.122.1/tcp/30334
2023-03-03 13:19:15 discovered: 12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust /ip4/172.17.0.1/tcp/30334
2023-03-03 13:19:15 discovered: 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 /ip4/172.17.0.1/tcp/30333
2023-03-03 13:19:15 discovered: 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 /ip4/172.18.0.1/tcp/30333
2023-03-03 13:19:15 discovered: 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 /ip4/192.168.122.1/tcp/30333
2023-03-03 13:19:20 💤 Idle (0 peers), best: #0 (0x1280…bbc0), finalized #0 (0x1280…bbc0), ⬇ 1.2kiB/s ⬆ 1.2kiB/s
2023-03-03 13:19:25 💤 Idle (0 peers), best: #0 (0x1280…bbc0), finalized #0 (0x1280…bbc0), ⬇ 0.2kiB/s ⬆ 0.2kiB/s
2023-03-03 13:19:30 💤 Idle (0 peers), best: #0 (0x1280…bbc0), finalized #0 (0x1280…bbc0), ⬇ 0 ⬆ 48 B/s
2023-03-03 13:19:35 💤 Idle (0 peers), best: #0 (0x1280…bbc0), finalized #0 (0x1280…bbc0), ⬇ 0.2kiB/s ⬆ 90 B/s
2023-03-03 13:19:40 💤 Idle (0 peers), best: #0 (0x1280…bbc0), finalized #0 (0x1280…bbc0), ⬇ 0 ⬆ 0
启动此节点后,您应该看到该节点没有连接的peers (no connected peers
)。因为这是一个受许可的网络,所以必须显式地授权节点连接。Alice和Bob节点是在chain_spec.rs
文件中配置的。所有其他节点必须通过调用Sudo
托盘手动添加。
授权第三个节点访问
本教程使用Sudo
托盘进行治理。因此,您可以使用Sudo
托盘调用节点授权(node-authorization
)托盘提供的addWellKnownNode
函数来添加第三个节点。为了简单起见,您可以使用Polkadot/Substrate Portal应用程序来访问Sudo
托盘。
-
在浏览器中打开Polkadot/Substrate Portal。
-
单击Developer并选择Sudo。
-
选择nodeAuthorization并选择addWellKnownNode(节点,所有者)。
-
在所需的
0x
前缀之后复制并粘贴Charlie拥有的节点的十六进制编码的对等标识符。 -
选择Charlie作为节点所有者。
-
单击“提交Sudo”。
-
在
Authorize transaction
中,请注意Alice开发帐户是默认的根管理帐户,并用作此调用的sudo
源,然后单击Sign and Submit。
-
单击
Network
并选择Explorer
以查看最近的交易。
在将交易包含在块中之后,您应该看到charlie
节点连接到alice和bob节点,并开始同步块。这三个节点可以使用本地网络默认启用的mDNS发现机制相互查找。还要确保所有本地防火墙都配置为允许mDNS。
如果您的节点不在同一个本地网络上,您应该使用命令行选项--no-mdns
禁用它。
5.10 提交交易所需的密钥
您应该注意到,任何帐户都可以用来签署和提交影响其他节点行为的交易。然而,要签署并提交一个影响你不拥有的节点的交易:
- 交易必须引用链数据(chain data)。
- 您必须在密钥存储库中拥有具有所需来源的帐户的签名密钥。
在本教程中,所有节点都可以访问开发帐户签名密钥。因此,您能够签署和提交影响任何连接节点的交易,使用帐户代表Charlie或Dave行事。如果您正在为现实世界的应用程序构建一个受许可的网络,那么节点操作员很可能只能访问他们自己的节点密钥,并且节点所有者帐户将被要求签署和提交影响节点的交易,而节点所有者帐户拥有签名密钥的控制权。
相关文章:

Substrate 基础教程(Tutorials) -- 授权特定节点
五、授权特定节点 在添加可信节点中,您看到了如何使用一组已知的验证器节点构建一个简单的网络。该教程演示了一个简化版的许可网络(permissioned network)。在一个被许可的网络中,只有被授权的节点(authorized nodes…...
使用qemu-img转换镜像格式
qemu功能强大,详细了解其功能请到官网查看 https://www.qemu.org/docs/master/system/images.html qemu-img能将RAW、qcow2、VMDK、VDI、VHD(vpc)、VHDX、qcow1或QED格式的镜像转换成VHD格式,也可以实现RAW和VHD格式的互相转换。 …...

Springboot怎么集成Thymeleaf模板引擎?
Thymeleaf介绍Thymeleaf,是一个XML/XHTML/HTML模板引擎,开源的java库,可以用于SpingMVC项目中,用于代替JSP、FreeMarker或者其他的模板引擎;页面与数据分离,提高了开发效率,让代码重用更容易。S…...

LiveGBS国标GB/T28181视频流媒体平台-功能视频集中录制存储云端录像H264|H265|HEVC视频存储
LiveGBS国标GB/T28181视频流媒体平台-视频集中录制存储云端录像H264|H265|HEVC视频存储1、云端录像存储2、手动配置录像2.1、按需录像2.2、一直录像3、录像计划3.1、录像计划入口3.2、新增录像计划3.3、编辑录像计划3.4、关联通道4、查看云端录像4.1、查看录像4.1.1、时间轴模式…...

IntelliJ IDEA如何整合Maven图文教程详解
Maven 1.Maven简述 Maven是一个构建工具,服务与构建.使用Maven配置好项目后,输入简单的命令,如:mvn clean install,Maven会帮我们处理那些繁琐的任务. Maven是跨平台的. Maven最大化的消除了构建的重复. Maven可以帮助我们标准化构建过程.所有的项目都是简单一致的,简化了学习…...

图数据库认证考试 NGCP 错题解析 vol.02:这 10 道题竟无一人全部答对
如果你读过「NebulaGraph 错题解析第一期」,大概知道在错题解析未出来之前,NebulaGraph 专业技能认证 NGCP(全称 NebulaGraph Certified Professional)的通过率仅有 16.7%。但是,经过上一轮 NebulaGraph 认证考试出题人…...
188888
81. 一个敏捷项目正在进行八次迭代中的第五次迭代。在最后一次迭代计划之后,团队得知市场上出现一个新的竞争对手,有必要更快地加快进程来确保不失去市场份额。 项目经理应该怎么做? A 将竞争对手的功能添加到产品积压待办清单中,…...

华为机试题:HJ99 自守数(python)
文章目录(1)题目描述(2)Python3实现(3)知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…...

如何提高推广邮件的发送成功率?
随着经济的发展,国际之间的贸易往来越加频繁,很多外贸企业需要发送大量的商业推广邮件,来获得销售订单开拓公司业务市场。 随之而来的问题也是越来越多,给众多的外贸企业带来诸多的困扰。外贸企业在发送推广邮件中究竟会遇到什么问…...

关于提高PX4抗风性
滚转角速率控制器:(MC_ROLLRATE_P, MC_ROLLRATE_I, MC_ROLLRATE_D) 滚转角速率控制器:(MC_PITCHRATE_P, MC_PITCHRATE_I,MC_PITCHRATE_D) 滚转角速率控制器…...

AVL 树实现
AVL 树的概念 也许因为插入的值不够随机,也许因为经过某些插入或删除操作,二叉搜索树可能会失去平衡,甚至可能退化为单链表,造成搜索效率低。 AVL Tree 是一个「加上了额外平衡条件」的二叉搜索树,其平衡条件的建立是…...
跟我学c++高级篇——模板元编程之八惰性加载
一、Lazy evaluation 惰性加载或者延迟计算,在前面的文章《跟我学c中级篇——迟延计算》中分析过。叫法怎么叫都可以,只要大家明白这个意思即可。Lazy evaluation一般可用于下面的情况: 1、模板中的对象非立刻的模板实例化,也就是…...
【Python入门第二十二天】Python 类和对象
Python 类/对象 Python 是一种面向对象的编程语言。 Python 中的几乎所有东西都是对象,拥有属性和方法。 类(Class)类似对象构造函数,或者是用于创建对象的“蓝图”。 创建类 如需创建类,请使用 class 关键字&…...
qml的进度条
QML是一种用于创建动态用户界面的声明式语言,它支持使用JavaScript表达式来定义属性绑定和信号处理器。在本文中,我们将介绍如何使用JavaScript在QML中绘制一个进度条(ProgressBar),并设置其前景色和背景色。进度条是一…...

Pycharm补丁包使用教程
虽然社区版在大多情况下已经够用,但是有很多功能都是没有的,对照起一些教程之类的就很不方便 现在直接教一种简单中的简单的补丁包使用方法 我这里用的是 pycharm 19.2.6 注意右下角的configure 一般别的方法都是 打开,然后添加路径&#…...

用VAE生成图像
用VAE生成图像自编码器AE,auto-encoderVAE讲讲为什么是log_var为什么要用重参数化技巧用VAE生成图像变分自编码器是自编码器的改进版本,自编码器AE是一种无监督学习,但它无法产生新的内容,变分自编码器对其潜在空间进行拓展&#…...

你只会说MVC模型是什么但是不会实现?今天带你走通Web、Servlet、MVC、SpringMVC。代码演示很清晰
文章目录HTTP请求和HTTP响应从0手写一个Web服务器,看看能有多累人使用Servlet实现一个服务器,看看多简单Serlvet的创建Servlet的运行Servlet的其他问题Servlet这么爽,我们简单地探索一下它的原理JSP跟Servlet合作啦,我们来看一下他…...

C++中邻接矩阵、邻接表、链式前向星具体用法及讲解
图论在提高组中几乎占据半壁江山,而今天要讲的就是如何存储一个图一.邻接矩阵原理要建立一个图,根本的要素就是边和点而想要让计算机存储边和点就需要用到一些数据结构邻接矩阵是最简单的他使用了一个二维数组,来表示一个图假设数组名为map那…...

appium的安装详解
安装appium 爬虫手机APP需要实现自动化,所以要使用appnium来实现点击,输入,滑动等操作。由于appnium的安装较为繁琐,所以特意整理一篇文章来展示安装的详细过程过程中。 安装appnium共有3个步骤 安装 Android SDK安装 JDK安装 …...

STM32之 串口
串口通信串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方 式的扩展接口。串行接口(Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简 单,只…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
flow_controllers
关键点: 流控制器类型: 同步(Sync):发布操作会阻塞,直到数据被确认发送。异步(Async):发布操作非阻塞,数据发送由后台线程处理。纯同步(PureSync…...

解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...

Canal环境搭建并实现和ES数据同步
作者:田超凡 日期:2025年6月7日 Canal安装,启动端口11111、8082: 安装canal-deployer服务端: https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...

动态规划-1035.不相交的线-力扣(LeetCode)
一、题目解析 光看题目要求和例图,感觉这题好麻烦,直线不能相交啊,每个数字只属于一条连线啊等等,但我们结合题目所给的信息和例图的内容,这不就是最长公共子序列吗?,我们把最长公共子序列连线起…...