substrate学习笔记7:使用substrate构建授权网络
1 说明
在本教程中,将使用node-authorization pallet来构建授权准入网络。无许可准入区块链网络我们比较常见,例如比特币、以太坊都是无准入的。那么授权准入网络在哪些地方可能出现呢?
可能有如下地方:
- 专用网络或者是联盟链网络;
- 高度管控的环境;
- 大规模测试预公开网络。
2 本节目标
本节的目标主要如下:
- 修改node-template工程添加node-authorization pallet。
- 加载部分节点并授权新节点加入网络。
3 添加node-authorization pallet
node-authorzation pallet是substrate FRAME中预先构建好的pallet,它主要用来配置授权网络的节点。每个节点定义一个PeerId然后用Vector简单封装。每个PeerID都被一个AccountID所有拥有。通过node-authorization pallet,我们有两种方式授权一个节点加入网络:
1、加入允许连接的已知节点集,需要用到治理(或者sudo)权限。
2、请求到特定节点的连接。此节点可以是已知节点,也可以是普通节点。
与PeerID关联的节点必须有且只有一个所有者,添加已知节点时指定其所有者。
节点的所有者可以添加和删除其节点的连接。
节点授权pallet集成了链下工作者来配置节点的连接。不过启动时请确保使用正确的命令标志参数,因为默认此链下工作者(配置节点)功能是禁用的。
3.1 编译node-template
执行如下命令:
# Fresh clone, if needed:
git clone -b v3.0.0 --depth 1 https://github.com/substrate-developer-hub/substrate-node-template
cd substrate-node-template
然后进行编译:
cd substrate-node-template/
cargo build --release
3.2 添加node-authorization
在runtime/Cargo.toml添加:
[dependencies.pallet-node-authorization]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
tag = 'devhub/latest'
version = '4.0.0-dev'
#--snip--
[features]
default = ['std']
std = [
#--snip--
'pallet-node-authorization/std',
#--snip--
]
在runtime/src/lib.rs添加如下代码:
/* --snip-- */
//runtime/src/lib.rs
use frame_system::EnsureRoot;
/* --snip-- */
parameter_types! {
pub const MaxWellKnownNodes: u32 = 8;
pub const MaxPeerIdLength: u32 = 128;
}
impl pallet_node_authorization::Config for Runtime {
type Event = Event;
type MaxWellKnownNodes = MaxWellKnownNodes;
type MaxPeerIdLength = MaxPeerIdLength;
type AddOrigin = EnsureRoot<AccountId>;
type RemoveOrigin = EnsureRoot<AccountId>;
type SwapOrigin = EnsureRoot<AccountId>;
type ResetOrigin = EnsureRoot<AccountId>;
type WeightInfo = ();
}
/* --snip-- */
然后在该文件中继续添加:
//runtime/src/lib.rs
construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = opaque::Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
/* --snip-- */
NodeAuthorization: pallet_node_authorization, // <-- add this line
/* --snip-- */
}
);
3.3 为node-authorzation添加genesis存储
在node/Cargo.toml中添加如下:
[dependencies]
bs58 = "0.4.0"
在node/src/chain_spec.rs中添加如下:
/* --snip-- */
use sp_core::OpaquePeerId; // A struct wraps Vec<u8>, represents as our `PeerId`.
use node_template_runtime::NodeAuthorizationConfig; // The genesis config that serves for our pallet.
/* --snip-- */
继续在node/src/chain_spec.rs中添加:
/// Configure initial storage state for FRAME modules.
fn testnet_genesis(
wasm_binary: &[u8],
initial_authorities: Vec<(AuraId, GrandpaId)>,
root_key: AccountId,
endowed_accounts: Vec<AccountId>,
_enable_println: bool,
) -> GenesisConfig {
GenesisConfig {
/* --snip-- */
/***添加下面这个代码块 ***/
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转换为字节。元组的第二个元素是AccountId,代表这个节点的所有者,这里我们使用substrate默认提供的账户:Alice和Bob。
可能有人会问12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2从哪里来,这里告诉大家,我们可以使用如下命令获取:
subkey generate-node-key
还可能有小伙伴会问,怎么看Alice和Bob的key,可以用如下命令:
subkey inspect //Alice # subkey要自己安装哈
编译运行:
cargo build --release
4 启动permission网络
4.1 获取节点keys和PeerIDs
Alice的节点信息如下:
# node key
c12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a
# peerid, generated from node key
12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2
# bs58 decoded peer id in hex:
0024080112201ce5f00ef6e89374afb625f1ae4c1546d31234e87e3c3f51a62b91dd6bfa57df
Bob的节点信息如下:
# node key
6ce3be907dbcabf20a9a5a60a712b4256a54196000a8ed4050d352bc113f8c58
# peer id, generated from node key
12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust
# bs58 decoded peer id in hex:
002408011220dacde7714d8551f674b8bb4b54239383c76a2b286fa436e93b2b7eb226bf4de7
4.2 使用Alice和Bob启动节点
启动Alice节点:
./target/release/node-template \
--chain=local \
--base-path /tmp/validator1 \
--alice \
--node-key=c12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a \
--port 30333 \
--ws-port 9944
启动Bob节点:
./target/release/node-template \
--chain=local \
--base-path /tmp/validator2 \
--bob \
--node-key=6ce3be907dbcabf20a9a5a60a712b4256a54196000a8ed4050d352bc113f8c58 \
--port 30334 \
--ws-port 9945
启动Charlie节点:
# node key
3a9d5b35b9fb4c42aafadeca046f6bf56107bd2579687f069b42646684b94d9e
# peer id, generated from node key
12D3KooWJvyP3VJYymTqG7eH4PM5rN4T2agk5cdNCfNymAqwqcvZ
# bs58 decoded peer id in hex:
002408011220876a7b4984f98006dc8d666e28b60de307309835d775e7755cc770328cdacf2e
使用polkadot.js apps可以进行查看。
4.3 添加Charlie节点
./target/release/node-template \
--chain=local \
--base-path /tmp/validator3 \
--name charlie \
--node-key=3a9d5b35b9fb4c42aafadeca046f6bf56107bd2579687f069b42646684b94d9e \
--port 30335 \
--ws-port=9946 \
--offchain-worker always
本作品采用《CC 协议》,转载必须注明作者和本文链接