substrate學習筆記7:使用substrate構建授權網路

linghuyichong發表於2022-03-30

在本教程中,將使用node-authorization pallet來構建授權准入網路。無許可准入區塊鏈網路我們比較常見,例如比特幣、以太坊都是無准入的。那麼授權准入網路在哪些地方可能出現呢?

可能有如下地方:

  • 專用網路或者是聯盟鏈網路;
  • 高度管控的環境;
  • 大規模測試預公開網路。

本節的目標主要如下:

  • 修改node-template工程新增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.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 協議》,轉載必須註明作者和本文連結
令狐一衝

相關文章