Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for 105 polkadot substrate : permissioned network
565.ee
565.ee

Posted on • Edited on

     

105 polkadot substrate : permissioned network

Introduction

Learning outcomes

Build the node template

Add the node-authorization pallet

Add genesis storage for our pallet

Obtaining Node Keys and PeerIDs

Alice and Bob Start the Network

Add charlie Node

Add Dave as a Sub-Node to Charlie

Substrate Tutorials , Substrate 教程

Contact 联系方式

• Introduction

In this tutorial, you will learn how to build a permissioned network with Substrate by using the node-authorization pallet. This tutorial should take you about 1 hour to complete.

You are probably already familiar with public or permissionless blockchain, where everyone is free to join the network by running a node. In a permissioned network, only authorized nodes are allowed to perform specific activities, like validate blocks and propagate transactions. Some examples of where permissioned blockchains may be desired:

• Private (or consortium) networks
• Highly regulated data environments (healthcare, B2B ledgers, etc.)
• Testing pre-public networks at scale

Before you start, we expect that:

• You have completed the Build a PoE Decentralized Application Tutorial.
• You are conceptually familiar with P2P Networking in Substrate. We recommend completing the Private Network Tutorial to get experience with this first.

• Learning outcomes

• Learn how to use the node-authorization pallet in your runtime
• Learn how to create a permissioned network consisting of multiple nodes

• Build the node template

• Clone the node template.

git clone https://github.com/substrate-developer-hub/substrate-node-template# We want to use the `latest` tag throughout all of this tutorialgit checkout latest
Enter fullscreen modeExit fullscreen mode

• Build the node template.

cd substrate-node-template/cargo build --release
Enter fullscreen modeExit fullscreen mode

• Add the node-authorization pallet

• First we must add the pallet to our runtime dependencies:
runtime/Cargo.toml

pallet-node-authorization = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.23" }#--snip--[features]default = ['std']std = [    #--snip--    'pallet-node-authorization/std',    #--snip--]
Enter fullscreen modeExit fullscreen mode

• We need to simulate the governance in our simple blockchain, so we just let a sudo admin rule, configuring the pallet's interface to EnsureRoot. In a production environment we should want to have governance based checking implemented here.
runtime/src/lib.rs

/* --snip-- */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-- */
Enter fullscreen modeExit fullscreen mode

• Finally, we are ready to put our pallet in construct_runtime macro with following extra line of code:
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-- */    });
Enter fullscreen modeExit fullscreen mode

• Add genesis storage for our pallet

• PeerId is encoded in bs58 format, so we need a new library bs58 in node/Cargo.toml to decode it to get its bytes.
node/cargo.toml

[dependencies]#--snip--bs58 = "0.4.0"#--snip--
Enter fullscreen modeExit fullscreen mode

• Now we add a proper genesis storage in node/src/chain_spec.rs. Similarly, import the necessary dependencies:
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-- */
Enter fullscreen modeExit fullscreen mode

• Adding our genesis config in the helper function testnet_genesis,
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 {        /* --snip-- */    /*** Add This Block Item ***/        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()                ),            ],        },    /* --snip-- */}
Enter fullscreen modeExit fullscreen mode

• Obtaining Node Keys and PeerIDs

• For Alice's well known node:

# Node Keyc12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a# Peer ID, generated from node key12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2# BS58 decoded Peer ID in hex:0x0024080112201ce5f00ef6e89374afb625f1ae4c1546d31234e87e3c3f51a62b91dd6bfa57df
Enter fullscreen modeExit fullscreen mode

• For Bob's well known node:

# Node Key6ce3be907dbcabf20a9a5a60a712b4256a54196000a8ed4050d352bc113f8c58# Peer ID, generated from node key12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust# BS58 decoded Peer ID in hex:0x002408011220dacde7714d8551f674b8bb4b54239383c76a2b286fa436e93b2b7eb226bf4de7
Enter fullscreen modeExit fullscreen mode

• For Charlie's NOT well known node:

# Node Key3a9d5b35b9fb4c42aafadeca046f6bf56107bd2579687f069b42646684b94d9e# Peer ID, generated from node key12D3KooWJvyP3VJYymTqG7eH4PM5rN4T2agk5cdNCfNymAqwqcvZ# BS58 decoded Peer ID in hex:0x002408011220876a7b4984f98006dc8d666e28b60de307309835d775e7755cc770328cdacf2e
Enter fullscreen modeExit fullscreen mode

• For Dave's sub-node

# Node Keya99331ff4f0e0a0434a6263da0a5823ea3afcfffe590c9f3014e6cf620f2b19a# Peer ID, generated from node key12D3KooWPHWFrfaJzxPnqnAYAoRUyAHHKqACmEycGTVmeVhQYuZN# BS58 decoded Peer ID in hex:0x002408011220c81bc1d7057a1511eb9496f056f6f53cdfe0e14c8bd5ffca47c70a8d76c1326d
Enter fullscreen modeExit fullscreen mode

The nodes of Alice and Bob are already configured in genesis storage and serve as well known nodes. We will later add Charlie's node into the set of well known nodes. Finally we will add the connection between Charlie's node and Dave's node without making Dave's node as a well known node.

• Alice and Bob Start the Network

• Let's start Alice's node first:

./target/release/node-template \--chain=local \--base-path /tmp/validator1 \--alice \--node-key=c12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a \--port 30333 \--ws-port 9944
Enter fullscreen modeExit fullscreen mode

• Start Bob's node:

# In a new terminal, leave Alice running./target/release/node-template \--chain=local \--base-path /tmp/validator2 \--bob \--node-key=6ce3be907dbcabf20a9a5a60a712b4256a54196000a8ed4050d352bc113f8c58 \--port 30334 \--ws-port 9945
Enter fullscreen modeExit fullscreen mode

After both nodes are started, you should be able to see new blocks authored and finalized in bother terminal logs. Now let's use the polkadot.js apps and check the well known nodes of our blockchain. Don't forget to switch to one of our local nodes running: 127.0.0.1:9944 or 127.0.0.1:9945.

Then, let's go to Developer page, Chain State sub-tab, and check the data stored in the nodeAuthorization pallet, wellKnownNodes storage. You should be able to see the peer ids of Alice and Bob's nodes, prefixed with 0x to show its bytes in hex format.

We can also check the owner of one node by querying the storage owners with the peer id of the node as input, you should get the account address of the owner.

• Add charlie Node

• Let's start Charlie's node

./target/release/node-template \--chain=local \--base-path /tmp/validator3 \--name charlie  \--node-key=3a9d5b35b9fb4c42aafadeca046f6bf56107bd2579687f069b42646684b94d9e \--port 30335 \--ws-port=9946 \--offchain-worker always
Enter fullscreen modeExit fullscreen mode

• Go to Developer page, Sudo tab, in apps and submit the nodeAuthorization - add_well_known_node call with the peer id in hex of Charlie's node and the owner is Charlie, of course. Note Alice is the valid sudo origin for this call.
add_well_known_node

• Add Dave as a Sub-Node to Charlie

• Let's add Dave's node, not as a well-known node, but a "sub-node" of Charlie. Dave will only be able to connect to Charlie to access the network. This is a security feature: as Charlie is therefore solely responsible for any connected sub-node peer. There is one point of access control for David in case they need to be removed or audited.

Start Dave's node with following command:

./target/release/node-template \--chain=local \--base-path /tmp/validator4 \--name dave \--node-key=a99331ff4f0e0a0434a6263da0a5823ea3afcfffe590c9f3014e6cf620f2b19a \--port 30336 \--ws-port 9947 \--offchain-worker always
Enter fullscreen modeExit fullscreen mode

After it was started, there is no available connections. This is a permissioned network, so first, Charlie needs to configure his node to allow the connection from Dave's node.

In the Developer Extrinsics page, get Charlie to submit an addConnections extrinsic. The first PeerId is the peer id in hex of Charlie's node. The connections is a list of allowed peer ids for Charlie's node, here we only add Dave's.
charlie_add_connections

Then, Dave needs to configure his node to allow the connection from Charlie's node. But before he adds this, Dave needs to claim his node, hopefully it's not too late!
dave_claim_node

Similarly, Dave can add connection from Charlie's node.
dave_add_connections

You should now see Dave is catching up blocks and only has one peer which belongs to Charlie! Restart Dave's node in case it's not connecting with Charlie right away.

You are at the end of this tutorial and are already learned about how to build a permissioned network. You can also play with other dispatchable calls like remove_well_known_node, remove_connections.

• Substrate Tutorials , Substrate 教程

CN 中文 GithubSubstrate 教程 : github.com/565ee/Substrate_CN

CN 中文 CSDNSubstrate 教程 : blog.csdn.net/wx468116118

EN 英文 GithubSubstrate Tutorials : github.com/565ee/Substrate_EN

EN 英文 dev.toSubstrate Tutorials : dev.to/565ee

• Contact 联系方式

Homepage :565.ee

GitHub :github.com/565ee

Email :565.eee@gmail.com

Facebook :facebook.com/565.ee

Twitter :twitter.com/565_eee

Telegram :t.me/ee_565

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Rust BlockChain Ethereum substrate SolanaDefi DappSolidity Truffle OpenZeppelin
  • Location
    china
  • Joined

More from565.ee

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp