feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
[package]
|
||||
name = "pezstaging-chain-spec-builder"
|
||||
version = "1.6.1"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
build = "build.rs"
|
||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
publish = true
|
||||
description = "Utility for building chain-specification files for Bizinikiwi-based runtimes based on `pezsp-genesis-builder`"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[[bin]]
|
||||
path = "bin/main.rs"
|
||||
name = "chain-spec-builder"
|
||||
|
||||
[lib]
|
||||
# Docs tests are not needed since the code samples that would be executed
|
||||
# are exercised already in the context of unit/integration tests, by virtue
|
||||
# of using a combination of encapsulation in functions + `docify::export`.
|
||||
# This is a practice we should use for new code samples if any.
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
clap = { features = ["derive"], workspace = true }
|
||||
docify = { workspace = true }
|
||||
pezsc-chain-spec = { features = [
|
||||
"clap",
|
||||
], workspace = true, default-features = true }
|
||||
serde = { workspace = true, default-features = true }
|
||||
serde_json = { workspace = true, default-features = true }
|
||||
pezsp-tracing = { workspace = true, default-features = true }
|
||||
|
||||
[dev-dependencies]
|
||||
cmd_lib = { workspace = true }
|
||||
pretty_assertions = { workspace = true }
|
||||
bizinikiwi-test-runtime = { workspace = true }
|
||||
|
||||
[features]
|
||||
# `cargo build --feature=generate-readme` updates the `README.md` file.
|
||||
generate-readme = []
|
||||
runtime-benchmarks = [
|
||||
"pezsc-chain-spec/runtime-benchmarks",
|
||||
"bizinikiwi-test-runtime/runtime-benchmarks",
|
||||
]
|
||||
@@ -0,0 +1,168 @@
|
||||
# Chain Spec Builder
|
||||
|
||||
Bizinikiwi's chain spec builder utility.
|
||||
|
||||
A chain-spec is short for `chain-specification`. See the [`pezsc-chain-spec`](https://crates.io/docs.rs/pezsc-chain-spec/latest/sc_chain_spec)
|
||||
for more information.
|
||||
|
||||
_Note:_ this binary is a more flexible alternative to the `build-spec` subcommand, contained in typical Bizinikiwi-based nodes.
|
||||
This particular binary is capable of interacting with [`pezsp-genesis-builder`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/index.html)
|
||||
implementation of any provided runtime allowing to build chain-spec JSON files.
|
||||
|
||||
See [`ChainSpecBuilderCmd`](https://docs.rs/pezstaging-chain-spec-builder/6.0.0/staging_chain_spec_builder/enum.ChainSpecBuilderCmd.html)
|
||||
for a list of available commands.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
cargo install pezstaging-chain-spec-builder --locked
|
||||
```
|
||||
|
||||
_Note:_ `chain-spec-builder` binary is published on [crates.io](https://crates.io) under
|
||||
[`pezstaging-chain-spec-builder`](https://crates.io/crates/pezstaging-chain-spec-builder) due to a name conflict.
|
||||
|
||||
## Usage
|
||||
|
||||
Please note that below usage is backed by integration tests. The commands' examples are wrapped
|
||||
around by the `bash!(...)` macro calls.
|
||||
|
||||
### Note for `CreateCmd`'s `para-id` flag
|
||||
|
||||
<!-- TODO: https://github.com/pezkuwichain/pezkuwi-sdk/issues/156 -->
|
||||
Runtimes relying on generating the chain specification with this tool should
|
||||
implement `cumulus_primitives_core::GetTeyrchainInfo` trait, a new runtime API
|
||||
designed to provide the teyrchain ID from the `teyrchain-info`
|
||||
pallet. The `para-id` flag can be used though if the runtime does not implement
|
||||
the runtime API, and the teyrchain id will be fetched by the node from chain
|
||||
specification. This can be especially useful when syncing a node from a state
|
||||
where the runtime does not implement `cumulus_primitives_core::GetTeyrchainInfo`.
|
||||
|
||||
For reference, generating a chain specification with a `para_id` field can be
|
||||
done like below:
|
||||
|
||||
```bash
|
||||
chain-spec-builder -c "/dev/stdout" create --relay-chain "dev" --para-id 1000 -r $runtime_path named-preset "staging"
|
||||
```
|
||||
|
||||
### Generate chains-spec using default config from runtime
|
||||
|
||||
Query the default genesis config from the provided runtime WASM blob and use it in the chain spec.
|
||||
|
||||
<!-- docify::embed!("tests/test.rs", cmd_create_default) -->
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
runtime function is called.
|
||||
|
||||
### Display the runtime's default `GenesisConfig`
|
||||
|
||||
<!-- docify::embed!("tests/test.rs", cmd_display_default_preset) -->
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
runtime function is called.
|
||||
|
||||
### Display the `GenesisConfig` preset with given name
|
||||
|
||||
<!-- docify::embed!("tests/test.rs", cmd_display_preset)-->
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
runtime function is called.
|
||||
|
||||
### List the names of `GenesisConfig` presets provided by runtime
|
||||
|
||||
<!-- docify::embed!("tests/test.rs", cmd_list_presets)-->
|
||||
|
||||
_Note:_ [`GenesisBuilder::preset_names`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.preset_names)
|
||||
runtime function is called.
|
||||
|
||||
### Generate chain spec using runtime provided genesis config preset
|
||||
|
||||
Patch the runtime's default genesis config with the named preset provided by the runtime and generate the plain
|
||||
version of chain spec:
|
||||
|
||||
<!-- docify::embed!("tests/test.rs", cmd_create_with_named_preset)-->
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
runtime functions are called.
|
||||
|
||||
### Generate raw storage chain spec using genesis config patch
|
||||
|
||||
Patch the runtime's default genesis config with provided `patch.json` and generate raw
|
||||
storage (`-s`) version of chain spec:
|
||||
|
||||
<!-- docify::embed!("tests/test.rs", cmd_create_with_patch_raw)-->
|
||||
|
||||
Refer to [_patch file_](#patch-file) for some details on the patch file format.
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
and
|
||||
[`GenesisBuilder::build_state`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state)
|
||||
runtime functions are called.
|
||||
|
||||
### Generate raw storage chain spec using full genesis config
|
||||
|
||||
Build the chain spec using provided full genesis config json file. No defaults will be used:
|
||||
|
||||
<!-- docify::embed!("tests/test.rs", cmd_create_full_raw)-->
|
||||
|
||||
Refer to [_full config file_](#full-genesis-config-file) for some details on the full file format.
|
||||
|
||||
_Note_: [`GenesisBuilder::build_state`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state)
|
||||
runtime function is called.
|
||||
|
||||
### Generate human readable chain spec using provided genesis config patch
|
||||
|
||||
<!-- docify::embed!("tests/test.rs", cmd_create_with_patch_plain)-->
|
||||
|
||||
Refer to [_patch file_](#patch-file) for some details on the patch file format.
|
||||
|
||||
### Generate human readable chain spec using provided full genesis config
|
||||
|
||||
<!-- docify::embed!("tests/test.rs", cmd_create_full_plain)-->
|
||||
|
||||
Refer to [_full config file_](#full-genesis-config-file) for some details on the full file format.
|
||||
|
||||
## Patch and full genesis config files
|
||||
|
||||
This section provides details on the files that can be used with `create patch` or `create full` subcommands.
|
||||
|
||||
### Patch file
|
||||
|
||||
The patch file for genesis config contains the key-value pairs valid for given runtime, that needs to be customized,
|
||||
e.g:
|
||||
|
||||
```ignore
|
||||
{
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
5000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"sudo": {
|
||||
"key": "5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The rest of genesis config keys will be initialized with default values.
|
||||
|
||||
### Full genesis config file
|
||||
|
||||
The full genesis config file must contain values for _all_ the keys present in the genesis config for given runtime. The
|
||||
format of the file is similar to patch format. Example is not provided here as it heavily depends on the runtime.
|
||||
|
||||
### Extra tools
|
||||
|
||||
The `chain-spec-builder` provides also some extra utilities: [`VerifyCmd`](https://docs.rs/pezstaging-chain-spec-builder/latest/staging_chain_spec_builder/struct.VerifyCmd.html),
|
||||
[`ConvertToRawCmd`](https://docs.rs/pezstaging-chain-spec-builder/latest/staging_chain_spec_builder/struct.ConvertToRawCmd.html),
|
||||
[`UpdateCodeCmd`](https://docs.rs/pezstaging-chain-spec-builder/latest/staging_chain_spec_builder/struct.UpdateCodeCmd.html).
|
||||
@@ -0,0 +1,206 @@
|
||||
# Chain Spec Builder
|
||||
|
||||
Bizinikiwi's chain spec builder utility.
|
||||
|
||||
A chain-spec is short for `chain-specification`. See the [`pezsc-chain-spec`](https://crates.io/docs.rs/pezsc-chain-spec/latest/sc_chain_spec)
|
||||
for more information.
|
||||
|
||||
_Note:_ this binary is a more flexible alternative to the `build-spec` subcommand, contained in typical Bizinikiwi-based nodes.
|
||||
This particular binary is capable of interacting with [`pezsp-genesis-builder`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/index.html)
|
||||
implementation of any provided runtime allowing to build chain-spec JSON files.
|
||||
|
||||
See [`ChainSpecBuilderCmd`](https://docs.rs/pezstaging-chain-spec-builder/6.0.0/staging_chain_spec_builder/enum.ChainSpecBuilderCmd.html)
|
||||
for a list of available commands.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
cargo install pezstaging-chain-spec-builder --locked
|
||||
```
|
||||
|
||||
_Note:_ `chain-spec-builder` binary is published on [crates.io](https://crates.io) under
|
||||
[`pezstaging-chain-spec-builder`](https://crates.io/crates/pezstaging-chain-spec-builder) due to a name conflict.
|
||||
|
||||
## Usage
|
||||
|
||||
Please note that below usage is backed by integration tests. The commands' examples are wrapped
|
||||
around by the `bash!(...)` macro calls.
|
||||
|
||||
### Note for `CreateCmd`'s `para-id` flag
|
||||
|
||||
<!-- TODO: https://github.com/pezkuwichain/pezkuwi-sdk/issues/156 -->
|
||||
Runtimes relying on generating the chain specification with this tool should
|
||||
implement `cumulus_primitives_core::GetTeyrchainInfo` trait, a new runtime API
|
||||
designed to provide the teyrchain ID from the `teyrchain-info`
|
||||
pallet. The `para-id` flag can be used though if the runtime does not implement
|
||||
the runtime API, and the teyrchain id will be fetched by the node from chain
|
||||
specification. This can be especially useful when syncing a node from a state
|
||||
where the runtime does not implement `cumulus_primitives_core::GetTeyrchainInfo`.
|
||||
|
||||
For reference, generating a chain specification with a `para_id` field can be
|
||||
done like below:
|
||||
|
||||
```bash
|
||||
chain-spec-builder -c "/dev/stdout" create --relay-chain "dev" --para-id 1000 -r $runtime_path named-preset "staging"
|
||||
```
|
||||
|
||||
### Generate chains-spec using default config from runtime
|
||||
|
||||
Query the default genesis config from the provided runtime WASM blob and use it in the chain spec.
|
||||
|
||||
```rust,ignore
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -r $runtime_path default
|
||||
)
|
||||
```
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
runtime function is called.
|
||||
|
||||
### Display the runtime's default `GenesisConfig`
|
||||
|
||||
```rust,ignore
|
||||
bash!(
|
||||
chain-spec-builder display-preset -r $runtime_path
|
||||
)
|
||||
```
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
runtime function is called.
|
||||
|
||||
### Display the `GenesisConfig` preset with given name
|
||||
|
||||
```rust,ignore
|
||||
fn cmd_display_preset(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder display-preset -r $runtime_path -p "staging"
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
runtime function is called.
|
||||
|
||||
### List the names of `GenesisConfig` presets provided by runtime
|
||||
|
||||
```rust,ignore
|
||||
bash!(
|
||||
chain-spec-builder list-presets -r $runtime_path
|
||||
)
|
||||
```
|
||||
|
||||
_Note:_ [`GenesisBuilder::preset_names`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.preset_names)
|
||||
runtime function is called.
|
||||
|
||||
### Generate chain spec using runtime provided genesis config preset
|
||||
|
||||
Patch the runtime's default genesis config with the named preset provided by the runtime and generate the plain
|
||||
version of chain spec:
|
||||
|
||||
```rust,ignore
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create --relay-chain "dev" -r $runtime_path named-preset "staging"
|
||||
)
|
||||
```
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
runtime functions are called.
|
||||
|
||||
### Generate raw storage chain spec using genesis config patch
|
||||
|
||||
Patch the runtime's default genesis config with provided `patch.json` and generate raw
|
||||
storage (`-s`) version of chain spec:
|
||||
|
||||
```rust,ignore
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path patch "tests/input/patch.json"
|
||||
)
|
||||
```
|
||||
|
||||
Refer to [_patch file_](#patch-file) for some details on the patch file format.
|
||||
|
||||
_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset)
|
||||
and
|
||||
[`GenesisBuilder::build_state`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state)
|
||||
runtime functions are called.
|
||||
|
||||
### Generate raw storage chain spec using full genesis config
|
||||
|
||||
Build the chain spec using provided full genesis config json file. No defaults will be used:
|
||||
|
||||
```rust,ignore
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path full "tests/input/full.json"
|
||||
)
|
||||
```
|
||||
|
||||
Refer to [_full config file_](#full-genesis-config-file) for some details on the full file format.
|
||||
|
||||
_Note_: [`GenesisBuilder::build_state`](https://docs.rs/pezsp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state)
|
||||
runtime function is called.
|
||||
|
||||
### Generate human readable chain spec using provided genesis config patch
|
||||
|
||||
```rust,ignore
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -r $runtime_path patch "tests/input/patch.json"
|
||||
)
|
||||
```
|
||||
|
||||
Refer to [_patch file_](#patch-file) for some details on the patch file format.
|
||||
|
||||
### Generate human readable chain spec using provided full genesis config
|
||||
|
||||
```rust,ignore
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -r $runtime_path full "tests/input/full.json"
|
||||
)
|
||||
```
|
||||
|
||||
Refer to [_full config file_](#full-genesis-config-file) for some details on the full file format.
|
||||
|
||||
## Patch and full genesis config files
|
||||
|
||||
This section provides details on the files that can be used with `create patch` or `create full` subcommands.
|
||||
|
||||
### Patch file
|
||||
|
||||
The patch file for genesis config contains the key-value pairs valid for given runtime, that needs to be customized,
|
||||
e.g:
|
||||
|
||||
```ignore
|
||||
{
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
5000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"sudo": {
|
||||
"key": "5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The rest of genesis config keys will be initialized with default values.
|
||||
|
||||
### Full genesis config file
|
||||
|
||||
The full genesis config file must contain values for _all_ the keys present in the genesis config for given runtime. The
|
||||
format of the file is similar to patch format. Example is not provided here as it heavily depends on the runtime.
|
||||
|
||||
### Extra tools
|
||||
|
||||
The `chain-spec-builder` provides also some extra utilities: [`VerifyCmd`](https://docs.rs/pezstaging-chain-spec-builder/latest/staging_chain_spec_builder/struct.VerifyCmd.html),
|
||||
[`ConvertToRawCmd`](https://docs.rs/pezstaging-chain-spec-builder/latest/staging_chain_spec_builder/struct.ConvertToRawCmd.html),
|
||||
[`UpdateCodeCmd`](https://docs.rs/pezstaging-chain-spec-builder/latest/staging_chain_spec_builder/struct.UpdateCodeCmd.html).
|
||||
@@ -0,0 +1,36 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use chain_spec_builder::ChainSpecBuilder;
|
||||
use clap::Parser;
|
||||
use pezstaging_chain_spec_builder as chain_spec_builder;
|
||||
|
||||
//avoid error message escaping
|
||||
fn main() {
|
||||
match inner_main() {
|
||||
Err(e) => eprintln!("{}", format!("{e}")),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn inner_main() -> Result<(), String> {
|
||||
pezsp_tracing::try_init_simple();
|
||||
|
||||
let builder = ChainSpecBuilder::parse();
|
||||
builder.run()
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
if let Ok(profile) = env::var("PROFILE") {
|
||||
println!("cargo:rustc-cfg=build_type=\"{}\"", profile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,478 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![doc = include_str!("../README.md")]
|
||||
#[cfg(feature = "generate-readme")]
|
||||
docify::compile_markdown!("README.docify.md", "README.md");
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use pezsc_chain_spec::{
|
||||
json_patch, set_code_substitute_in_json_chain_spec, update_code_in_json_chain_spec, ChainType,
|
||||
GenericChainSpec, GenesisConfigBuilderRuntimeCaller,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
/// A utility to easily create a chain spec definition.
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(rename_all = "kebab-case", version, about)]
|
||||
pub struct ChainSpecBuilder {
|
||||
#[command(subcommand)]
|
||||
pub command: ChainSpecBuilderCmd,
|
||||
/// The path where the chain spec should be saved.
|
||||
#[arg(long, short, default_value = "./chain_spec.json")]
|
||||
pub chain_spec_path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
#[command(rename_all = "kebab-case")]
|
||||
pub enum ChainSpecBuilderCmd {
|
||||
Create(CreateCmd),
|
||||
Verify(VerifyCmd),
|
||||
UpdateCode(UpdateCodeCmd),
|
||||
ConvertToRaw(ConvertToRawCmd),
|
||||
ListPresets(ListPresetsCmd),
|
||||
DisplayPreset(DisplayPresetCmd),
|
||||
AddCodeSubstitute(AddCodeSubstituteCmd),
|
||||
}
|
||||
|
||||
/// Create a new chain spec by interacting with the provided runtime wasm blob.
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct CreateCmd {
|
||||
/// The name of chain.
|
||||
#[arg(long, short = 'n', default_value = "Custom")]
|
||||
chain_name: String,
|
||||
/// The chain id.
|
||||
#[arg(long, short = 'i', default_value = "custom")]
|
||||
chain_id: String,
|
||||
/// The chain type.
|
||||
#[arg(value_enum, short = 't', default_value = "live")]
|
||||
chain_type: ChainType,
|
||||
/// The para ID for your chain.
|
||||
#[arg(long, value_enum, short = 'p', requires = "relay_chain")]
|
||||
pub para_id: Option<u32>,
|
||||
/// The relay chain you wish to connect to.
|
||||
#[arg(long, value_enum, short = 'c')]
|
||||
pub relay_chain: Option<String>,
|
||||
/// The path to runtime wasm blob.
|
||||
#[arg(long, short, alias = "runtime-wasm-path")]
|
||||
runtime: PathBuf,
|
||||
/// Export chainspec as raw storage.
|
||||
#[arg(long, short = 's')]
|
||||
raw_storage: bool,
|
||||
/// Verify the genesis config. This silently generates the raw storage from genesis config. Any
|
||||
/// errors will be reported.
|
||||
#[arg(long, short = 'v')]
|
||||
verify: bool,
|
||||
/// Chain properties in `KEY=VALUE` format.
|
||||
///
|
||||
/// Multiple `KEY=VALUE` entries can be specified and separated by a comma.
|
||||
///
|
||||
/// Example: `--properties tokenSymbol=UNIT,tokenDecimals=12,ss58Format=42,isEthereum=false`
|
||||
/// Or: `--properties tokenSymbol=UNIT --properties tokenDecimals=12 --properties ss58Format=42
|
||||
/// --properties=isEthereum=false`
|
||||
///
|
||||
/// The first uses comma as separation and the second passes the argument multiple times. Both
|
||||
/// styles can also be mixed.
|
||||
#[arg(long, default_value = "tokenSymbol=UNIT,tokenDecimals=12")]
|
||||
pub properties: Vec<String>,
|
||||
#[command(subcommand)]
|
||||
action: GenesisBuildAction,
|
||||
|
||||
/// Allows to provide the runtime code blob, instead of reading it from the provided file path.
|
||||
#[clap(skip)]
|
||||
code: Option<Cow<'static, [u8]>>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug, Clone)]
|
||||
enum GenesisBuildAction {
|
||||
Patch(PatchCmd),
|
||||
Full(FullCmd),
|
||||
Default(DefaultCmd),
|
||||
NamedPreset(NamedPresetCmd),
|
||||
}
|
||||
|
||||
/// Patches the runtime's default genesis config with provided patch.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct PatchCmd {
|
||||
/// The path to the runtime genesis config patch.
|
||||
patch_path: PathBuf,
|
||||
}
|
||||
|
||||
/// Build the genesis config for runtime using provided json file. No defaults will be used.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct FullCmd {
|
||||
/// The path to the full runtime genesis config json file.
|
||||
config_path: PathBuf,
|
||||
}
|
||||
|
||||
/// Gets the default genesis config for the runtime and uses it in ChainSpec. Please note that
|
||||
/// default genesis config may not be valid. For some runtimes initial values should be added there
|
||||
/// (e.g. session keys, babe epoch).
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DefaultCmd {}
|
||||
|
||||
/// Uses named preset provided by runtime to build the chains spec.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct NamedPresetCmd {
|
||||
preset_name: String,
|
||||
}
|
||||
|
||||
/// Updates the code in the provided input chain spec.
|
||||
///
|
||||
/// The code field of the chain spec will be updated with the runtime provided in the
|
||||
/// command line. This operation supports both plain and raw formats.
|
||||
///
|
||||
/// This command does not update chain-spec file in-place. The result of this command will be stored
|
||||
/// in a file given as `-c/--chain-spec-path` command line argument.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
pub struct UpdateCodeCmd {
|
||||
/// Chain spec to be updated.
|
||||
///
|
||||
/// Please note that the file will not be updated in-place.
|
||||
pub input_chain_spec: PathBuf,
|
||||
/// The path to new runtime wasm blob to be stored into chain-spec.
|
||||
#[arg(alias = "runtime-wasm-path")]
|
||||
pub runtime: PathBuf,
|
||||
}
|
||||
|
||||
/// Add a code substitute in the chain spec.
|
||||
///
|
||||
/// The `codeSubstitute` object of the chain spec will be updated with the block height as key and
|
||||
/// runtime code as value. This operation supports both plain and raw formats. The `codeSubstitute`
|
||||
/// field instructs the node to use the provided runtime code at the given block height. This is
|
||||
/// useful when the chain can not progress on its own due to a bug that prevents block-building.
|
||||
///
|
||||
/// Note: For teyrchains, the validation function on the relaychain needs to be adjusted too,
|
||||
/// otherwise blocks built using the substituted teyrchain runtime will be rejected.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
pub struct AddCodeSubstituteCmd {
|
||||
/// Chain spec to be updated.
|
||||
pub input_chain_spec: PathBuf,
|
||||
/// New runtime wasm blob that should replace the existing code.
|
||||
#[arg(alias = "runtime-wasm-path")]
|
||||
pub runtime: PathBuf,
|
||||
/// The block height at which the code should be substituted.
|
||||
pub block_height: u64,
|
||||
}
|
||||
|
||||
/// Converts the given chain spec into the raw format.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
pub struct ConvertToRawCmd {
|
||||
/// Chain spec to be converted.
|
||||
pub input_chain_spec: PathBuf,
|
||||
}
|
||||
|
||||
/// Lists available presets
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
pub struct ListPresetsCmd {
|
||||
/// The path to runtime wasm blob.
|
||||
#[arg(long, short, alias = "runtime-wasm-path")]
|
||||
pub runtime: PathBuf,
|
||||
}
|
||||
|
||||
/// Displays given preset
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
pub struct DisplayPresetCmd {
|
||||
/// The path to runtime wasm blob.
|
||||
#[arg(long, short, alias = "runtime-wasm-path")]
|
||||
pub runtime: PathBuf,
|
||||
/// Preset to be displayed. If none is given default will be displayed.
|
||||
#[arg(long, short)]
|
||||
pub preset_name: Option<String>,
|
||||
}
|
||||
|
||||
/// Verifies the provided input chain spec.
|
||||
///
|
||||
/// Silently checks if given input chain spec can be converted to raw. It allows to check if all
|
||||
/// RuntimeGenesisConfig fields are properly initialized and if the json does not contain invalid
|
||||
/// fields.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
pub struct VerifyCmd {
|
||||
/// Chain spec to be verified.
|
||||
pub input_chain_spec: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone)]
|
||||
pub struct TeyrchainExtension {
|
||||
/// The relay chain of the Teyrchain.
|
||||
pub relay_chain: String,
|
||||
/// The id of the Teyrchain.
|
||||
pub para_id: Option<u32>,
|
||||
}
|
||||
|
||||
type ChainSpec = GenericChainSpec<()>;
|
||||
|
||||
impl ChainSpecBuilder {
|
||||
/// Executes the internal command.
|
||||
pub fn run(&self) -> Result<(), String> {
|
||||
let chain_spec_path = self.chain_spec_path.to_path_buf();
|
||||
|
||||
match &self.command {
|
||||
ChainSpecBuilderCmd::Create(cmd) => {
|
||||
let chain_spec_json = generate_chain_spec_for_runtime(&cmd)?;
|
||||
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
|
||||
},
|
||||
ChainSpecBuilderCmd::UpdateCode(UpdateCodeCmd {
|
||||
ref input_chain_spec,
|
||||
ref runtime,
|
||||
}) => {
|
||||
let mut chain_spec_json = extract_chain_spec_json(input_chain_spec.as_path())?;
|
||||
|
||||
update_code_in_json_chain_spec(
|
||||
&mut chain_spec_json,
|
||||
&fs::read(runtime.as_path())
|
||||
.map_err(|e| format!("Wasm blob file could not be read: {e}"))?[..],
|
||||
);
|
||||
|
||||
let chain_spec_json = serde_json::to_string_pretty(&chain_spec_json)
|
||||
.map_err(|e| format!("to pretty failed: {e}"))?;
|
||||
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
|
||||
},
|
||||
ChainSpecBuilderCmd::AddCodeSubstitute(AddCodeSubstituteCmd {
|
||||
ref input_chain_spec,
|
||||
ref runtime,
|
||||
block_height,
|
||||
}) => {
|
||||
let mut chain_spec_json = extract_chain_spec_json(input_chain_spec.as_path())?;
|
||||
|
||||
set_code_substitute_in_json_chain_spec(
|
||||
&mut chain_spec_json,
|
||||
&fs::read(runtime.as_path())
|
||||
.map_err(|e| format!("Wasm blob file could not be read: {e}"))?[..],
|
||||
*block_height,
|
||||
);
|
||||
let chain_spec_json = serde_json::to_string_pretty(&chain_spec_json)
|
||||
.map_err(|e| format!("to pretty failed: {e}"))?;
|
||||
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
|
||||
},
|
||||
ChainSpecBuilderCmd::ConvertToRaw(ConvertToRawCmd { ref input_chain_spec }) => {
|
||||
let chain_spec = ChainSpec::from_json_file(input_chain_spec.clone())?;
|
||||
|
||||
let mut genesis_json =
|
||||
serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(true)?)
|
||||
.map_err(|e| format!("Conversion to json failed: {e}"))?;
|
||||
|
||||
// We want to extract only raw genesis ("genesis::raw" key), and apply it as a patch
|
||||
// for the original json file.
|
||||
genesis_json.as_object_mut().map(|map| {
|
||||
map.retain(|key, _| key == "genesis");
|
||||
});
|
||||
|
||||
let mut org_chain_spec_json = extract_chain_spec_json(input_chain_spec.as_path())?;
|
||||
|
||||
// The original plain genesis ("genesis::runtimeGenesis") is no longer needed, so
|
||||
// just remove it:
|
||||
org_chain_spec_json
|
||||
.get_mut("genesis")
|
||||
.and_then(|genesis| genesis.as_object_mut())
|
||||
.and_then(|genesis| genesis.remove("runtimeGenesis"));
|
||||
json_patch::merge(&mut org_chain_spec_json, genesis_json);
|
||||
|
||||
let chain_spec_json = serde_json::to_string_pretty(&org_chain_spec_json)
|
||||
.map_err(|e| format!("Conversion to pretty failed: {e}"))?;
|
||||
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
|
||||
},
|
||||
ChainSpecBuilderCmd::Verify(VerifyCmd { ref input_chain_spec }) => {
|
||||
let chain_spec = ChainSpec::from_json_file(input_chain_spec.clone())?;
|
||||
serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(true)?)
|
||||
.map_err(|e| format!("Conversion to json failed: {e}"))?;
|
||||
},
|
||||
ChainSpecBuilderCmd::ListPresets(ListPresetsCmd { runtime }) => {
|
||||
let code = fs::read(runtime.as_path())
|
||||
.map_err(|e| format!("wasm blob shall be readable {e}"))?;
|
||||
let caller: GenesisConfigBuilderRuntimeCaller =
|
||||
GenesisConfigBuilderRuntimeCaller::new(&code[..]);
|
||||
let presets = caller
|
||||
.preset_names()
|
||||
.map_err(|e| format!("getting default config from runtime should work: {e}"))?;
|
||||
println!("{}", serde_json::json!({"presets":presets}).to_string());
|
||||
},
|
||||
ChainSpecBuilderCmd::DisplayPreset(DisplayPresetCmd { runtime, preset_name }) => {
|
||||
let code = fs::read(runtime.as_path())
|
||||
.map_err(|e| format!("wasm blob shall be readable {e}"))?;
|
||||
let caller: GenesisConfigBuilderRuntimeCaller =
|
||||
GenesisConfigBuilderRuntimeCaller::new(&code[..]);
|
||||
let preset = caller
|
||||
.get_named_preset(preset_name.as_ref())
|
||||
.map_err(|e| format!("getting default config from runtime should work: {e}"))?;
|
||||
println!("{preset}");
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sets the code used by [`CreateCmd`]
|
||||
///
|
||||
/// The file pointed by `CreateCmd::runtime` field will not be read. Provided blob will used
|
||||
/// instead for chain spec generation.
|
||||
pub fn set_create_cmd_runtime_code(&mut self, code: Cow<'static, [u8]>) {
|
||||
match &mut self.command {
|
||||
ChainSpecBuilderCmd::Create(cmd) => {
|
||||
cmd.code = Some(code);
|
||||
},
|
||||
_ => {
|
||||
panic!("Overwriting code blob is only supported for CreateCmd");
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn process_action<T: Serialize + Clone + Sync + 'static>(
|
||||
cmd: &CreateCmd,
|
||||
code: &[u8],
|
||||
builder: pezsc_chain_spec::ChainSpecBuilder<T>,
|
||||
) -> Result<String, String> {
|
||||
let builder = match cmd.action {
|
||||
GenesisBuildAction::NamedPreset(NamedPresetCmd { ref preset_name }) =>
|
||||
builder.with_genesis_config_preset_name(&preset_name),
|
||||
GenesisBuildAction::Patch(PatchCmd { ref patch_path }) => {
|
||||
let patch = fs::read(patch_path.as_path())
|
||||
.map_err(|e| format!("patch file {patch_path:?} shall be readable: {e}"))?;
|
||||
builder.with_genesis_config_patch(serde_json::from_slice::<Value>(&patch[..]).map_err(
|
||||
|e| format!("patch file {patch_path:?} shall contain a valid json: {e}"),
|
||||
)?)
|
||||
},
|
||||
GenesisBuildAction::Full(FullCmd { ref config_path }) => {
|
||||
let config = fs::read(config_path.as_path())
|
||||
.map_err(|e| format!("config file {config_path:?} shall be readable: {e}"))?;
|
||||
builder.with_genesis_config(serde_json::from_slice::<Value>(&config[..]).map_err(
|
||||
|e| format!("config file {config_path:?} shall contain a valid json: {e}"),
|
||||
)?)
|
||||
},
|
||||
GenesisBuildAction::Default(DefaultCmd {}) => {
|
||||
let caller: GenesisConfigBuilderRuntimeCaller =
|
||||
GenesisConfigBuilderRuntimeCaller::new(&code);
|
||||
let default_config = caller
|
||||
.get_default_config()
|
||||
.map_err(|e| format!("getting default config from runtime should work: {e}"))?;
|
||||
builder.with_genesis_config(default_config)
|
||||
},
|
||||
};
|
||||
|
||||
let chain_spec = builder.build();
|
||||
|
||||
match (cmd.verify, cmd.raw_storage) {
|
||||
(_, true) => chain_spec.as_json(true),
|
||||
(true, false) => {
|
||||
chain_spec.as_json(true)?;
|
||||
println!("Genesis config verification: OK");
|
||||
chain_spec.as_json(false)
|
||||
},
|
||||
(false, false) => chain_spec.as_json(false),
|
||||
}
|
||||
}
|
||||
|
||||
impl CreateCmd {
|
||||
/// Returns the associated runtime code.
|
||||
///
|
||||
/// If the code blob was previously set, returns it. Otherwise reads the file.
|
||||
fn get_runtime_code(&self) -> Result<Cow<'static, [u8]>, String> {
|
||||
Ok(if let Some(code) = self.code.clone() {
|
||||
code
|
||||
} else {
|
||||
fs::read(self.runtime.as_path())
|
||||
.map_err(|e| format!("wasm blob shall be readable {e}"))?
|
||||
.into()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses chain properties passed as a comma-separated KEY=VALUE pairs.
|
||||
fn parse_properties(raw: &String, props: &mut pezsc_chain_spec::Properties) -> Result<(), String> {
|
||||
for pair in raw.split(',') {
|
||||
let mut iter = pair.splitn(2, '=');
|
||||
let key = iter
|
||||
.next()
|
||||
.ok_or_else(|| format!("Invalid chain property key: {pair}"))?
|
||||
.trim()
|
||||
.to_owned();
|
||||
let value_str = iter
|
||||
.next()
|
||||
.ok_or_else(|| format!("Invalid chain property value for key: {key}"))?
|
||||
.trim();
|
||||
|
||||
// Try to parse as bool, number, or fallback to String
|
||||
let value = match value_str.parse::<bool>() {
|
||||
Ok(b) => Value::Bool(b),
|
||||
Err(_) => match value_str.parse::<u32>() {
|
||||
Ok(i) => Value::Number(i.into()),
|
||||
Err(_) => Value::String(value_str.to_string()),
|
||||
},
|
||||
};
|
||||
|
||||
props.insert(key, value);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Processes `CreateCmd` and returns string representation of JSON version of `ChainSpec`.
|
||||
pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result<String, String> {
|
||||
let code = cmd.get_runtime_code()?;
|
||||
|
||||
let chain_type = &cmd.chain_type;
|
||||
|
||||
let mut properties = pezsc_chain_spec::Properties::new();
|
||||
for raw in &cmd.properties {
|
||||
parse_properties(raw, &mut properties)?;
|
||||
}
|
||||
|
||||
let builder = ChainSpec::builder(&code[..], Default::default())
|
||||
.with_name(&cmd.chain_name[..])
|
||||
.with_id(&cmd.chain_id[..])
|
||||
.with_properties(properties)
|
||||
.with_chain_type(chain_type.clone());
|
||||
|
||||
let chain_spec_json_string = process_action(&cmd, &code[..], builder)?;
|
||||
let teyrchain_properties = cmd.relay_chain.as_ref().map(|rc| {
|
||||
cmd.para_id
|
||||
.map(|para_id| {
|
||||
serde_json::json!({
|
||||
"relay_chain": rc,
|
||||
"para_id": para_id,
|
||||
})
|
||||
})
|
||||
.unwrap_or(serde_json::json!({
|
||||
"relay_chain": rc,
|
||||
}))
|
||||
});
|
||||
|
||||
let chain_spec = teyrchain_properties
|
||||
.map(|props| {
|
||||
let chain_spec_json_blob = serde_json::from_str(chain_spec_json_string.as_str())
|
||||
.map_err(|e| format!("deserialization a json failed {e}"));
|
||||
chain_spec_json_blob.and_then(|mut cs| {
|
||||
json_patch::merge(&mut cs, props);
|
||||
serde_json::to_string_pretty(&cs).map_err(|e| format!("to pretty failed: {e}"))
|
||||
})
|
||||
})
|
||||
.unwrap_or(Ok(chain_spec_json_string));
|
||||
chain_spec
|
||||
}
|
||||
|
||||
/// Extract any chain spec and convert it to JSON
|
||||
fn extract_chain_spec_json(input_chain_spec: &Path) -> Result<serde_json::Value, String> {
|
||||
let chain_spec = &fs::read(input_chain_spec)
|
||||
.map_err(|e| format!("Provided chain spec could not be read: {e}"))?;
|
||||
|
||||
serde_json::from_slice(&chain_spec).map_err(|e| format!("Conversion to json failed: {e}"))
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"bootNodes": [],
|
||||
"chainType": "Live",
|
||||
"codeSubstitutes": {
|
||||
"100": "0x040506"
|
||||
},
|
||||
"custom_field": "custom_value",
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x010203",
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
1,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": []
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": []
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "custom",
|
||||
"name": "Custom",
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"protocolId": null,
|
||||
"relay_chain": "pezkuwichain-local",
|
||||
"telemetryEndpoints": null
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"relay_chain": "pezkuwichain-local",
|
||||
"custom_field": "custom_value",
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"childrenDefault": {},
|
||||
"top": {
|
||||
"0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x00",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000002",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000",
|
||||
"0x3a636f6465": "0x010203",
|
||||
"0x3a65787472696e7369635f696e646578": "0x00000000",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x0000000000000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x010203",
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
1,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": [],
|
||||
"devAccounts": null
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": []
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"top": {
|
||||
"0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000002",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92c2a60ec6dd16cd8ab911865ecf7555b186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e": "0x00000000000000000000000001000000000000000080e03779c311000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000",
|
||||
"0x3a636f6465": "0x010203",
|
||||
"0x3a65787472696e7369635f696e646578": "0x00000000",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00806d8176de1800",
|
||||
"0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000"
|
||||
},
|
||||
"childrenDefault": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "test_chain",
|
||||
"id": "100",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"relay_chain": "pezkuwichain-local",
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x010203",
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
1,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": [],
|
||||
"devAccounts": null
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": []
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x010203",
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [
|
||||
[
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
1
|
||||
],
|
||||
[
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
|
||||
1
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
1
|
||||
]
|
||||
],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
2,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
2000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
2000000000000000
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
5000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b"
|
||||
]
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x010203",
|
||||
"patch": {
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
1000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "test_chain",
|
||||
"id": "100",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x010203",
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
1,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": [],
|
||||
"devAccounts": null
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": []
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x010203",
|
||||
"patch": {
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
5000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 6,
|
||||
"tokenSymbol": "TEST",
|
||||
"ss58Prefix": 42,
|
||||
"isEthereum": false
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x010203",
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
1,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": [],
|
||||
"devAccounts": null
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": []
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
1,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": [],
|
||||
"devAccounts": null
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": []
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [
|
||||
[
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
1
|
||||
],
|
||||
[
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
|
||||
1
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
1
|
||||
]
|
||||
],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
2,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
2000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
2000000000000000
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
5000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b"
|
||||
]
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"top": {
|
||||
"0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c0100000000000000186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e0100000000000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c0100000000000000186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e0100000000000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0200000000000000040000000000000002",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92c2a60ec6dd16cd8ab911865ecf7555b186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e": "0x00000000000000000000000001000000000000000080e03779c311000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x000000000000000000000000010000000000000000008d49fd1a07000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x000000000000000000000000010000000000000000008d49fd1a07000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000",
|
||||
"0x3a65787472696e7369635f696e646578": "0x00000000",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x0080faca73f91f00",
|
||||
"0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000"
|
||||
},
|
||||
"childrenDefault": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"bootNodes": [],
|
||||
"chainType": "Live",
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"patch": {
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
1000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "custom",
|
||||
"name": "Custom",
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"protocolId": null,
|
||||
"relay_chain": "dev",
|
||||
"telemetryEndpoints": null
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"patch": {
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
5000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"top": {
|
||||
"0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000002",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92c2a60ec6dd16cd8ab911865ecf7555b186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e": "0x00000000000000000000000001000000000000000080e03779c311000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000",
|
||||
"0x3a65787472696e7369635f696e646578": "0x00000000",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00806d8176de1800",
|
||||
"0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000"
|
||||
},
|
||||
"childrenDefault": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"babe":{"authorities":[],"epochConfig":{"allowed_slots":"PrimaryAndSecondaryVRFSlots","c":[1,4]}},"balances":{"balances":[], "devAccounts": null},"bizinikiwiTest":{"authorities":[]},"system":{}}
|
||||
@@ -0,0 +1 @@
|
||||
{"balances":{"balances":[["5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",1000000000000000],["5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",1000000000000000]]},"bizinikiwiTest":{"authorities":["5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY","5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL"]}}
|
||||
@@ -0,0 +1 @@
|
||||
{"presets":["foobar","staging"]}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"relay_chain": "pezkuwichain-local",
|
||||
"custom_field": "custom_value",
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x040506",
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
1,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": []
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": []
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"top": {
|
||||
"0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000002",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92c2a60ec6dd16cd8ab911865ecf7555b186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e": "0x00000000000000000000000001000000000000000080e03779c311000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000",
|
||||
"0x3a636f6465": "0x040506",
|
||||
"0x3a65787472696e7369635f696e646578": "0x00000000",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00806d8176de1800"
|
||||
},
|
||||
"childrenDefault": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"relay_chain": "pezkuwichain-local",
|
||||
"custom_field": "custom_value",
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"code": "0x010203",
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
1,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": []
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": []
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "Custom",
|
||||
"id": "custom",
|
||||
"chainType": "Live",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": {
|
||||
"tokenDecimals": 12,
|
||||
"tokenSymbol": "UNIT"
|
||||
},
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"top": {
|
||||
"0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000002",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92c2a60ec6dd16cd8ab911865ecf7555b186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e": "0x00000000000000000000000001000000000000000080e03779c311000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000",
|
||||
"0x3a636f6465": "0x010203",
|
||||
"0x3a65787472696e7369635f696e646578": "0x00000000",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00806d8176de1800"
|
||||
},
|
||||
"childrenDefault": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"babe": {
|
||||
"authorities": [
|
||||
["5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", 1],
|
||||
["5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", 1],
|
||||
["5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b", 1]
|
||||
],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
|
||||
"c": [
|
||||
2,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
2000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
2000000000000000
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
5000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b"
|
||||
]
|
||||
},
|
||||
"system": {}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
1000000000000000
|
||||
],
|
||||
[
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b",
|
||||
5000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"bizinikiwiTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
|
||||
"5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::fs::File;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use cmd_lib::spawn_with_output;
|
||||
use pretty_assertions::assert_eq;
|
||||
use pezsc_chain_spec::update_code_in_json_chain_spec;
|
||||
use serde_json::{from_reader, from_str, Value};
|
||||
use pezstaging_chain_spec_builder::ChainSpecBuilder;
|
||||
|
||||
// note: the runtime path will not be read, runtime code will be set directly, to avoid hassle with
|
||||
// creating the wasm file or providing a valid existing path during test execution.
|
||||
const DUMMY_PATH: &str = "fake-runtime-path";
|
||||
|
||||
const OUTPUT_FILE: &str = "/tmp/chain_spec_builder.test_output_file.json";
|
||||
|
||||
// Used for running commands visually pleasing in doc tests.
|
||||
macro_rules! bash(
|
||||
( chain-spec-builder $($a:tt)* ) => {{
|
||||
let bin_path = env!("CARGO_BIN_EXE_chain-spec-builder");
|
||||
spawn_with_output!(
|
||||
$bin_path $($a)*
|
||||
)
|
||||
.expect("a process running. qed")
|
||||
.wait_with_output()
|
||||
.expect("to get output. qed.")
|
||||
}}
|
||||
);
|
||||
|
||||
// Used specifically in docs tests.
|
||||
fn doc_assert(output: String, expected_output_path: &str, remove_code: bool) {
|
||||
let expected: Value =
|
||||
from_reader(File::open(expected_output_path).unwrap()).expect("a valid JSON. qed.");
|
||||
let output = if remove_code {
|
||||
let mut output: Value = from_str(output.as_str()).expect("a valid JSON. qed.");
|
||||
// Remove code sections gracefully for both `plain` & `raw`.
|
||||
output
|
||||
.get_mut("genesis")
|
||||
.and_then(|inner| inner.get_mut("runtimeGenesis"))
|
||||
.and_then(|inner| inner.as_object_mut())
|
||||
.and_then(|inner| inner.remove("code"));
|
||||
output
|
||||
.get_mut("genesis")
|
||||
.and_then(|inner| inner.get_mut("raw"))
|
||||
.and_then(|inner| inner.get_mut("top"))
|
||||
.and_then(|inner| inner.as_object_mut())
|
||||
.and_then(|inner| inner.remove("0x3a636f6465"));
|
||||
output
|
||||
} else {
|
||||
from_str::<Value>(output.as_str()).expect("a valid JSON. qed.")
|
||||
};
|
||||
assert_eq!(output, expected);
|
||||
}
|
||||
|
||||
/// Asserts that the JSON in output file matches the JSON in expected file.
|
||||
///
|
||||
/// This helper function reads the JSON content from the file at `OUTPUT_FILE + suffix` path. If the
|
||||
/// `overwrite_code` flag is set, it updates the output chain specification with a sample code
|
||||
/// vector `[1, 2, 3]` (to avoid bulky *expected* files), and then compares it against the JSON
|
||||
/// content from the given `expected_path`.
|
||||
fn assert_output_eq_expected(overwrite_code: bool, output_suffix: &str, expected_path: &str) {
|
||||
let path = OUTPUT_FILE.to_string() + output_suffix;
|
||||
let mut output: serde_json::Value =
|
||||
serde_json::from_reader(File::open(path.clone()).unwrap()).unwrap();
|
||||
if overwrite_code {
|
||||
update_code_in_json_chain_spec(&mut output, &vec![1, 2, 3]);
|
||||
}
|
||||
let expected: serde_json::Value =
|
||||
serde_json::from_reader(File::open(expected_path).unwrap()).unwrap();
|
||||
|
||||
assert_eq!(expected, output);
|
||||
|
||||
std::fs::remove_file(path).expect("Failed to delete file");
|
||||
}
|
||||
|
||||
fn get_builder(suffix: &str, command_args: Vec<&str>) -> ChainSpecBuilder {
|
||||
let path = OUTPUT_FILE.to_string() + suffix;
|
||||
let mut base_args = vec!["dummy", "-c", path.as_str()];
|
||||
base_args.extend(command_args);
|
||||
ChainSpecBuilder::parse_from(base_args)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_default() {
|
||||
const SUFFIX: &str = "00";
|
||||
let mut builder = get_builder(SUFFIX, vec!["create", "-r", DUMMY_PATH, "default"]);
|
||||
builder.set_create_cmd_runtime_code(bizinikiwi_test_runtime::WASM_BINARY.unwrap().into());
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/create_default.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_with_named_preset() {
|
||||
const SUFFIX: &str = "01";
|
||||
let mut builder =
|
||||
get_builder(SUFFIX, vec!["create", "-r", DUMMY_PATH, "named-preset", "staging"]);
|
||||
builder.set_create_cmd_runtime_code(bizinikiwi_test_runtime::WASM_BINARY.unwrap().into());
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/create_with_named_preset.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_with_patch() {
|
||||
const SUFFIX: &str = "02";
|
||||
let mut builder =
|
||||
get_builder(SUFFIX, vec!["create", "-r", DUMMY_PATH, "patch", "tests/input/patch.json"]);
|
||||
builder.set_create_cmd_runtime_code(bizinikiwi_test_runtime::WASM_BINARY.unwrap().into());
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/create_with_patch.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_with_full() {
|
||||
const SUFFIX: &str = "03";
|
||||
let mut builder =
|
||||
get_builder(SUFFIX, vec!["create", "-r", DUMMY_PATH, "full", "tests/input/full.json"]);
|
||||
builder.set_create_cmd_runtime_code(bizinikiwi_test_runtime::WASM_BINARY.unwrap().into());
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/create_with_full.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_with_params() {
|
||||
const SUFFIX: &str = "04";
|
||||
let mut builder = get_builder(
|
||||
SUFFIX,
|
||||
vec!["create", "-r", DUMMY_PATH, "-n", "test_chain", "-i", "100", "-t", "live", "default"],
|
||||
);
|
||||
builder.set_create_cmd_runtime_code(bizinikiwi_test_runtime::WASM_BINARY.unwrap().into());
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/create_with_params.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_teyrchain() {
|
||||
const SUFFIX: &str = "05";
|
||||
let mut builder = get_builder(
|
||||
SUFFIX,
|
||||
vec![
|
||||
"create",
|
||||
"-r",
|
||||
DUMMY_PATH,
|
||||
"-n",
|
||||
"test_chain",
|
||||
"-i",
|
||||
"100",
|
||||
"-t",
|
||||
"live",
|
||||
"--relay-chain",
|
||||
"pezkuwichain-local",
|
||||
"default",
|
||||
],
|
||||
);
|
||||
builder.set_create_cmd_runtime_code(bizinikiwi_test_runtime::WASM_BINARY.unwrap().into());
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/create_teyrchain.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_raw_storage() {
|
||||
const SUFFIX: &str = "06";
|
||||
let mut builder = get_builder(
|
||||
SUFFIX,
|
||||
vec!["create", "-r", DUMMY_PATH, "-s", "patch", "tests/input/patch.json"],
|
||||
);
|
||||
builder.set_create_cmd_runtime_code(bizinikiwi_test_runtime::WASM_BINARY.unwrap().into());
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/create_raw_storage.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_code() {
|
||||
const SUFFIX: &str = "07";
|
||||
let builder = get_builder(
|
||||
SUFFIX,
|
||||
vec!["update-code", "tests/input/chain_spec_plain.json", "tests/input/code_040506.blob"],
|
||||
);
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(false, SUFFIX, "tests/expected/update_code.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_code_raw() {
|
||||
const SUFFIX: &str = "08";
|
||||
let builder = get_builder(
|
||||
SUFFIX,
|
||||
vec!["update-code", "tests/input/chain_spec_raw.json", "tests/input/code_040506.blob"],
|
||||
);
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(false, SUFFIX, "tests/expected/update_code_raw.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_to_raw() {
|
||||
const SUFFIX: &str = "09";
|
||||
let builder =
|
||||
get_builder(SUFFIX, vec!["convert-to-raw", "tests/input/chain_spec_conversion_test.json"]);
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/convert_to_raw.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_code_substitute() {
|
||||
const SUFFIX: &str = "10";
|
||||
let builder = get_builder(
|
||||
SUFFIX,
|
||||
vec![
|
||||
"add-code-substitute",
|
||||
"tests/input/chain_spec_plain.json",
|
||||
"tests/input/code_040506.blob",
|
||||
"100",
|
||||
],
|
||||
);
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/add_code_substitute.json");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_with_properties() {
|
||||
const SUFFIX: &str = "11";
|
||||
let mut builder = get_builder(
|
||||
SUFFIX,
|
||||
vec![
|
||||
"create",
|
||||
"-r",
|
||||
DUMMY_PATH,
|
||||
"--properties",
|
||||
"tokenSymbol=TEST,tokenDecimals=6",
|
||||
"--properties",
|
||||
"isEthereum=false",
|
||||
"--properties",
|
||||
"ss58Prefix=42",
|
||||
"default",
|
||||
],
|
||||
);
|
||||
builder.set_create_cmd_runtime_code(bizinikiwi_test_runtime::WASM_BINARY.unwrap().into());
|
||||
builder.run().unwrap();
|
||||
assert_output_eq_expected(true, SUFFIX, "tests/expected/create_with_properties.json");
|
||||
}
|
||||
|
||||
#[docify::export_content]
|
||||
fn cmd_create_default(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -r $runtime_path default
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_default() {
|
||||
doc_assert(
|
||||
cmd_create_default(
|
||||
bizinikiwi_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"),
|
||||
),
|
||||
"tests/expected/doc/create_default.json",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[docify::export_content]
|
||||
fn cmd_display_default_preset(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder display-preset -r $runtime_path
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_default_preset() {
|
||||
doc_assert(
|
||||
cmd_display_default_preset(
|
||||
bizinikiwi_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed."),
|
||||
),
|
||||
"tests/expected/doc/display_preset.json",
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[docify::export]
|
||||
fn cmd_display_preset(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder display-preset -r $runtime_path -p "staging"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_preset() {
|
||||
doc_assert(
|
||||
cmd_display_preset(
|
||||
bizinikiwi_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"),
|
||||
),
|
||||
"tests/expected/doc/display_preset_staging.json",
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[docify::export_content]
|
||||
fn cmd_list_presets(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder list-presets -r $runtime_path
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_presets() {
|
||||
doc_assert(
|
||||
cmd_list_presets(
|
||||
bizinikiwi_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"),
|
||||
),
|
||||
"tests/expected/doc/list_presets.json",
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[docify::export_content]
|
||||
fn cmd_create_with_named_preset(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create --relay-chain "dev" -r $runtime_path named-preset "staging"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_with_named_preset() {
|
||||
doc_assert(
|
||||
cmd_create_with_named_preset(
|
||||
bizinikiwi_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"),
|
||||
),
|
||||
"tests/expected/doc/create_with_named_preset_staging.json",
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
#[docify::export_content]
|
||||
fn cmd_create_with_patch_raw(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path patch "tests/input/patch.json"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_with_patch_raw() {
|
||||
doc_assert(
|
||||
cmd_create_with_patch_raw(
|
||||
bizinikiwi_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"),
|
||||
),
|
||||
"tests/expected/doc/create_with_patch_raw.json",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[docify::export_content]
|
||||
fn cmd_create_with_patch_plain(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -r $runtime_path patch "tests/input/patch.json"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_with_patch_plain() {
|
||||
doc_assert(
|
||||
cmd_create_with_patch_plain(
|
||||
bizinikiwi_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"),
|
||||
),
|
||||
"tests/expected/doc/create_with_patch_plain.json",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[docify::export_content]
|
||||
fn cmd_create_full_plain(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -r $runtime_path full "tests/input/full.json"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_full_plain() {
|
||||
doc_assert(
|
||||
cmd_create_full_plain(
|
||||
bizinikiwi_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"),
|
||||
),
|
||||
"tests/expected/doc/create_full_plain.json",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[docify::export_content]
|
||||
fn cmd_create_full_raw(runtime_path: &str) -> String {
|
||||
bash!(
|
||||
chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path full "tests/input/full.json"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_full_raw() {
|
||||
doc_assert(
|
||||
cmd_create_full_raw(
|
||||
bizinikiwi_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"),
|
||||
),
|
||||
"tests/expected/doc/create_full_raw.json",
|
||||
true,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
[package]
|
||||
name = "subkey"
|
||||
version = "9.0.0"
|
||||
authors.workspace = true
|
||||
description = "Generate and restore keys for Bizinikiwi based chains such as Pezkuwi, Kusama and a growing number of teyrchains and Bizinikiwi based projects."
|
||||
edition.workspace = true
|
||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
readme = "README.md"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[[bin]]
|
||||
path = "src/main.rs"
|
||||
name = "subkey"
|
||||
|
||||
[dependencies]
|
||||
clap = { features = ["derive"], workspace = true }
|
||||
pezsc-cli = { workspace = true, default-features = true }
|
||||
|
||||
[features]
|
||||
runtime-benchmarks = ["pezsc-cli/runtime-benchmarks"]
|
||||
@@ -0,0 +1,288 @@
|
||||
# Subkey
|
||||
|
||||
Subkey is a commandline utility included with Bizinikiwi. It allows generating and restoring keys for Bizinikiwi based
|
||||
chains such as PezkuwiChain, Kusama and a growing number of teyrchains and Bizinikiwi based projects.
|
||||
|
||||
`subkey` provides a few sub-commands to generate keys, check keys, sign messages, verify messages, etc...
|
||||
|
||||
You can see the full list of commands with `subkey --help`. Most commands have additional help available with for
|
||||
instance `subkey generate --help` for the `generate` command.
|
||||
|
||||
## Safety first
|
||||
|
||||
`subkey` does not need an internet connection to work. Indeed, for the best security, you should be using `subkey` on a
|
||||
machine that is **not connected** to the internet.
|
||||
|
||||
`subkey` deals with **seeds** and **private keys**. Make sure to use `subkey` in a safe environment (ie. no one looking
|
||||
over your shoulder) and on a safe computer (ie. no one able to check your command history).
|
||||
|
||||
If you save any output of `subkey` into a file, make sure to apply proper permissions and/or delete the file as soon as
|
||||
possible.
|
||||
|
||||
## Usage
|
||||
|
||||
The following guide explains *some* of the `subkey` commands. For the full list and the most up to date documentation,
|
||||
make sure to check the integrated help with `subkey --help`.
|
||||
|
||||
### Install with Cargo
|
||||
|
||||
You will need to have the Bizinikiwi build dependencies to install Subkey. Use the following two commands to install the
|
||||
dependencies and Subkey, respectively:
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
# Install only `subkey`, at a specific version of the subkey crate
|
||||
cargo install --force subkey --git https://github.com/paritytech/bizinikiwi --version <SET VERSION> --locked
|
||||
# If you run into issues building, you likely are missing deps defined in https://docs.pezkuwichain.io/install/
|
||||
```
|
||||
|
||||
### Run in a container
|
||||
|
||||
```bash
|
||||
# Use `--pull=always` with the `latest` tag, or specify a version in a tag
|
||||
docker run -it --pull=always docker.io/parity/subkey:latest <command to subkey>
|
||||
```
|
||||
|
||||
### Generate a random account
|
||||
|
||||
Generating a new key is as simple as running:
|
||||
|
||||
```bash
|
||||
subkey generate
|
||||
```
|
||||
|
||||
The output looks similar to:
|
||||
|
||||
```text
|
||||
Secret phrase `hotel forest jar hover kite book view eight stuff angle legend defense` is account:
|
||||
Secret seed: 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
Public key (hex): 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
Account ID: 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
SS58 Address: 5Hpm9fq3W3dQgwWpAwDS2ZHKAdnk86QRCu7iX4GnmDxycrte
|
||||
```
|
||||
|
||||
---
|
||||
☠️ DO NT RE-USE ANY OF THE SEEDS AND SECRETS FROM THIS PAGE ☠️.
|
||||
|
||||
You can read more about security and risks in [SECURITY.md](./SECURITY.md) and in the [PezkuwiChain
|
||||
Wiki](https://wiki.network.pezkuwichain.io/docs/learn-account-generation).
|
||||
|
||||
---
|
||||
|
||||
The output above shows a **secret phrase** (also called **mnemonic phrase**) and the **secret seed** (also called
|
||||
**Private Key**). Those 2 secrets are the pieces of information you MUST keep safe and secret. All the other information
|
||||
below can be derived from those secrets.
|
||||
|
||||
The output above also shows the **public key** and the **Account ID**. Those are the independent from the network where
|
||||
you will use the key.
|
||||
|
||||
The **SS58 address** (or **Public Address**) of a new account is a representation of the public keys of an account for
|
||||
a given network (for instance Kusama or PezkuwiChain).
|
||||
|
||||
You can read more about the [SS58 format in the Bizinikiwi Docs](https://docs.pezkuwichain.io/reference/address-formats/)
|
||||
and see the list of reserved prefixes in the [SS58 Registry](https://github.com/paritytech/ss58-registry).
|
||||
|
||||
For instance, considering the previous seed `0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d` the
|
||||
SS58 addresses are:
|
||||
|
||||
- PezkuwiChain: `16m4J167Mptt8UXL8aGSAi7U2FnPpPxZHPrCgMG9KJzVoFqM`
|
||||
- Kusama: `JLNozAv8QeLSbLFwe2UvWeKKE4yvmDbfGxTuiYkF2BUMx4M`
|
||||
|
||||
### Json output
|
||||
|
||||
`subkey` can also generate the output as *json*. This is useful for automation.
|
||||
|
||||
command:
|
||||
|
||||
```bash
|
||||
subkey generate --output-type json
|
||||
```
|
||||
|
||||
output:
|
||||
|
||||
```json
|
||||
{
|
||||
"accountId": "0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515",
|
||||
"publicKey": "0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515",
|
||||
"secretPhrase": "hotel forest jar hover kite book view eight stuff angle legend defense",
|
||||
"secretSeed": "0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d",
|
||||
"ss58Address": "5Hpm9fq3W3dQgwWpAwDS2ZHKAdnk86QRCu7iX4GnmDxycrte"
|
||||
}
|
||||
```
|
||||
|
||||
So if you only want to get the `secretSeed` for instance, you can use:
|
||||
|
||||
command:
|
||||
|
||||
```bash
|
||||
subkey generate --output-type json | jq -r .secretSeed
|
||||
```
|
||||
|
||||
output:
|
||||
|
||||
```text
|
||||
0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
```
|
||||
|
||||
### Additional user-defined password
|
||||
|
||||
`subkey` supports an additional user-defined secret that will be appended to the seed. Let's see the following example:
|
||||
|
||||
```bash
|
||||
subkey generate --password extra_secret
|
||||
```
|
||||
|
||||
output:
|
||||
|
||||
```text
|
||||
Secret phrase `soup lyrics media market way crouch elevator put moon useful question wide` is account:
|
||||
Secret seed: 0xe7cfd179d6537a676cb94bac3b5c5c9cb1550e846ac4541040d077dfbac2e7fd
|
||||
Public key (hex): 0xf6a233c3e1de1a2ae0486100b460b3ce3d7231ddfe9dadabbd35ab968c70905d
|
||||
Account ID: 0xf6a233c3e1de1a2ae0486100b460b3ce3d7231ddfe9dadabbd35ab968c70905d
|
||||
SS58 Address: 5He5pZpc7AJ8evPuab37vJF6KkFDqq9uDq2WXh877Qw6iaVC
|
||||
```
|
||||
|
||||
Using the `inspect` command (see more details below), we see that knowing only the **secret seed** is no longer
|
||||
sufficient to recover the account:
|
||||
|
||||
```bash
|
||||
subkey inspect "soup lyrics media market way crouch elevator put moon useful question wide"
|
||||
```
|
||||
|
||||
which recovers the account `5Fe4sqj2K4fRuzEGvToi4KATqZfiDU7TqynjXG6PZE2dxwyh` and not
|
||||
`5He5pZpc7AJ8evPuab37vJF6KkFDqq9uDq2WXh877Qw6iaVC` as we expected. The additional user-defined **password**
|
||||
(`extra_secret` in our example) is now required to fully recover the account. Let's inspect the previous mnemonic,
|
||||
this time passing also the required `password` as shown below:
|
||||
|
||||
```bash
|
||||
subkey inspect --password extra_secret "soup lyrics media market way crouch elevator put moon useful question wide"
|
||||
```
|
||||
|
||||
This time, we properly recovered `5He5pZpc7AJ8evPuab37vJF6KkFDqq9uDq2WXh877Qw6iaVC`.
|
||||
|
||||
### Inspecting a key
|
||||
|
||||
If you have *some data* about a key, `subkey inspect` will help you discover more information about it.
|
||||
|
||||
If you have **secrets** that you would like to verify for instance, you can use:
|
||||
|
||||
```bash
|
||||
subkey inspect < mnemonic | seed >
|
||||
```
|
||||
|
||||
If you have only **public data**, you can see a subset of the information:
|
||||
|
||||
```bash
|
||||
subkey inspect --public < pubkey | address >
|
||||
```
|
||||
|
||||
**NOTE**: While you will be able to recover the secret seed from the mnemonic, the opposite is not possible.
|
||||
|
||||
**NOTE**: For obvious reasons, the **secrets** cannot be recovered from passing **public data** such as `pubkey` or
|
||||
`address` as input.
|
||||
|
||||
command:
|
||||
|
||||
```bash
|
||||
subkey inspect 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
```
|
||||
|
||||
output:
|
||||
|
||||
```text
|
||||
Secret Key URI `0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d` is account:
|
||||
Secret seed: 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
Public key (hex): 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
Account ID: 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
SS58 Address: 5Hpm9fq3W3dQgwWpAwDS2ZHKAdnk86QRCu7iX4GnmDxycrte
|
||||
```
|
||||
|
||||
### Signing
|
||||
|
||||
`subkey` allows using a **secret key** to sign a random message. The signature can then be verified by anyone using your
|
||||
**public key**:
|
||||
|
||||
```bash
|
||||
echo -n <msg> | subkey sign --suri <seed|mnemonic>
|
||||
```
|
||||
|
||||
example:
|
||||
|
||||
```text
|
||||
MESSAGE=hello
|
||||
SURI=0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
echo -n $MESSAGE | subkey sign --suri $SURI
|
||||
```
|
||||
|
||||
output:
|
||||
|
||||
```text
|
||||
9201af3788ad4f986b800853c79da47155f2e08fde2070d866be4c27ab060466fea0623dc2b51f4392f4c61f25381a62848dd66c5d8217fae3858e469ebd668c
|
||||
```
|
||||
|
||||
**NOTE**: Each run of the `sign` command will yield a different output. While each signature is different, they are all
|
||||
valid.
|
||||
|
||||
### Verifying a signature
|
||||
|
||||
Given a message, a signature and an address, `subkey` can verify whether the **message** has been digitally signed by
|
||||
the holder (or one of the holders) of the **private key** for the given **address**:
|
||||
|
||||
```bash
|
||||
echo -n <msg> | subkey verify <sig> <address>
|
||||
```
|
||||
|
||||
example:
|
||||
|
||||
```bash
|
||||
MESSAGE=hello
|
||||
URI=0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
SIGNATURE=9201af3788ad4f986b800853c79da47155f2e08fde2070d866be4c27ab060466fea0623dc2b51f4392f4c61f25381a62848dd66c5d8217fae3858e469ebd668c
|
||||
echo -n $MESSAGE | subkey verify $SIGNATURE $URI
|
||||
```
|
||||
|
||||
output:
|
||||
|
||||
```text
|
||||
Signature verifies correctly.
|
||||
```
|
||||
|
||||
A failure looks like:
|
||||
|
||||
```text
|
||||
Error: SignatureInvalid
|
||||
```
|
||||
|
||||
### Using the vanity generator
|
||||
|
||||
You can use the included vanity generator to find a seed that provides an address which includes the desired pattern. Be
|
||||
warned, depending on your hardware this may take a while.
|
||||
|
||||
command:
|
||||
|
||||
```bash
|
||||
subkey vanity --network pezkuwi --pattern bob
|
||||
```
|
||||
|
||||
output:
|
||||
|
||||
```text
|
||||
Generating key containing pattern 'bob'
|
||||
best: 190 == top: 189
|
||||
Secret Key URI `0x8c9a73097f235b84021a446bc2826a00c690ea0be3e0d81a84931cb4146d6691` is account:
|
||||
Secret seed: 0x8c9a73097f235b84021a446bc2826a00c690ea0be3e0d81a84931cb4146d6691
|
||||
Public key (hex): 0x1a8b32e95c1f571118ea0b84801264c3c70f823e320d099e5de31b9b1f18f843
|
||||
Account ID: 0x1a8b32e95c1f571118ea0b84801264c3c70f823e320d099e5de31b9b1f18f843
|
||||
SS58 Address: 1bobYxBPjZWRPbVo35aSwci1u5Zmq8P6J2jpa4kkudBZMqE
|
||||
```
|
||||
|
||||
`Bob` now got a nice address starting with their name: 1**bob**YxBPjZWRPbVo35aSwci1u5Zmq8P6J2jpa4kkudBZMqE.
|
||||
|
||||
**Note**: While `Bob`, having a short name (3 chars), got a result rather quickly, it will take much longer for `Alice`
|
||||
who has a much longer name, thus the chances to generate a random address that contains the chain `alice` will be much
|
||||
smaller.
|
||||
|
||||
## License
|
||||
|
||||
License: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
@@ -0,0 +1,32 @@
|
||||
# Keys and Security
|
||||
|
||||
The following information is not exhaustive but meant to prevent the most common mistakes. You can read more about
|
||||
security and risks in the [Pezkuwi Wiki](https://wiki.network.pezkuwichain.io/docs/learn-account-generation). The Pezkuwi
|
||||
network has a few **test networks**, e.g. **Zagros**. Test networks are a great way to experiment and learn safely as
|
||||
you can lose tokens on those networks without any financial consequences.
|
||||
|
||||
`subkey` generates and provides 2 pieces of **secret** information:
|
||||
- **secret phrase**: a bunch of words, exactly 12 by default (can be 12, 15, 18, 21 or 24)
|
||||
- **secret seed**: a big hexadecimal value
|
||||
|
||||
There are 2 risks related to private keys:
|
||||
- loss of keys: this can happen if you don't have a proper backup
|
||||
- leak of the keys: this can unfortunately happen in many ways, including malware, phishing, key logger, backups on
|
||||
system that are online and not properly secured
|
||||
|
||||
You want to ensure that:
|
||||
- you **do not lose** those secrets
|
||||
- **no one but you can access** those secrets
|
||||
|
||||
☠️ **DO NOT SHARE** your mnemonic phrase or secret seed with ANYONE under **ANY** circumstances. Doing so would give
|
||||
them access to your funds and to send transactions on your behalf.
|
||||
|
||||
☠️ If someone is asking for your **secret** phrase or **secret** seed, you can be **SURE** they are attempting to steal
|
||||
your funds.
|
||||
|
||||
✅ It is however fine to share your **SS58 Address** as this is meant to be public information and is needed by anyone
|
||||
you want to be able to make transfer to or otherwise interact with your account. They will only ever need your **Public
|
||||
Address**.
|
||||
|
||||
⚠️ While using the same key on multiple networks is possible, it is usually **not** recommended unless you have good
|
||||
motivations for doing so and understand the associated risks and drawbacks.
|
||||
@@ -0,0 +1,359 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! # Subkey
|
||||
//!
|
||||
//! Subkey is a commandline utility included with Bizinikiwi. It allows generating and restoring keys
|
||||
//! for Bizinikiwi based chains such as Pezkuwi, Kusama and a growing number of teyrchains and
|
||||
//! Bizinikiwi based projects.
|
||||
|
||||
//! `subkey` provides a few sub-commands to generate keys, check keys, sign messages, verify
|
||||
//! messages, etc...
|
||||
//!
|
||||
//! You can see the full list of commands with `subkey --help`. Most commands have additional help
|
||||
//! available with for instance `subkey generate --help` for the `generate` command.
|
||||
//!
|
||||
//! ## Safety first
|
||||
//!
|
||||
//! `subkey` does not need an internet connection to work. Indeed, for the best security, you should
|
||||
//! be using `subkey` on a machine that is **not connected** to the internet.
|
||||
//!
|
||||
//! `subkey` deals with **seeds** and **private keys**. Make sure to use `subkey` in a safe
|
||||
//! environment (ie. no one looking over your shoulder) and on a safe computer (ie. no one able to
|
||||
//! check your command history).
|
||||
//!
|
||||
//! If you save any output of `subkey` into a file, make sure to apply proper permissions and/or
|
||||
//! delete the file as soon as possible.
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! The following guide explains *some* of the `subkey` commands. For the full list and the most up
|
||||
//! to date documentation, make sure to check the integrated help with `subkey --help`.
|
||||
//!
|
||||
//! ### Install with Cargo
|
||||
//!
|
||||
//! You will need to have the Bizinikiwi build dependencies to install Subkey. Use the following two
|
||||
//! commands to install the dependencies and Subkey, respectively:
|
||||
//!
|
||||
//! Command:
|
||||
//!
|
||||
//! ```bash
|
||||
//! # Install only `subkey`, at a specific version of the subkey crate
|
||||
//! cargo install --force subkey --git https://github.com/paritytech/bizinikiwi --version <SET VERSION> --locked
|
||||
//! # If you run into issues building, you likely are missing deps defined in https://docs.pezkuwichain.io/install/
|
||||
//! ```
|
||||
//!
|
||||
//! ### Run in a container
|
||||
//!
|
||||
//! ```bash
|
||||
//! # Use `--pull=always` with the `latest` tag, or specify a version in a tag
|
||||
//! docker run -it --pull=always docker.io/parity/subkey:latest <command to subkey>
|
||||
//! ```
|
||||
//!
|
||||
//! ### Generate a random account
|
||||
//!
|
||||
//! Generating a new key is as simple as running:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey generate
|
||||
//! ```
|
||||
//!
|
||||
//! The output looks similar to:
|
||||
//!
|
||||
//! ```text
|
||||
//! Secret phrase `hotel forest jar hover kite book view eight stuff angle legend defense` is account:
|
||||
//! Secret seed: 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
//! Public key (hex): 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
//! Account ID: 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
//! SS58 Address: 5Hpm9fq3W3dQgwWpAwDS2ZHKAdnk86QRCu7iX4GnmDxycrte
|
||||
//! ```
|
||||
//!
|
||||
//! ---
|
||||
//! ☠️ DO NT RE-USE ANY OF THE SEEDS AND SECRETS FROM THIS PAGE ☠️.
|
||||
//!
|
||||
//! You can read more about security and risks in [SECURITY.md](./SECURITY.md) and in the [Pezkuwi Wiki](https://wiki.network.pezkuwichain.io/learn/learn-accounts/#account-generation).
|
||||
//!
|
||||
//! ---
|
||||
//!
|
||||
//! The output above shows a **secret phrase** (also called **mnemonic phrase**) and the **secret
|
||||
//! seed** (also called **Private Key**). Those 2 secrets are the pieces of information you MUST
|
||||
//! keep safe and secret. All the other information below can be derived from those secrets.
|
||||
//!
|
||||
//! The output above also show the **public key** and the **Account ID**. Those are the independent
|
||||
//! from the network where you will use the key.
|
||||
//!
|
||||
//! The **SS58 address** (or **Public Address**) of a new account is a representation of the public
|
||||
//! keys of an account for a given network (for instance Kusama or Pezkuwi).
|
||||
//!
|
||||
//! You can read more about the [SS58 format in the Bizinikiwi Docs](https://docs.pezkuwichain.io/reference/address-formats/) and see the list of reserved prefixes in the [SS58 Registry](https://github.com/paritytech/ss58-registry).
|
||||
//!
|
||||
//! For instance, considering the previous seed
|
||||
//! `0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d` the SS58 addresses are:
|
||||
//!
|
||||
//! - Pezkuwi: `16m4J167Mptt8UXL8aGSAi7U2FnPpPxZHPrCgMG9KJzVoFqM`
|
||||
//! - Kusama: `JLNozAv8QeLSbLFwe2UvWeKKE4yvmDbfGxTuiYkF2BUMx4M`
|
||||
//!
|
||||
//! ### Json output
|
||||
//!
|
||||
//! `subkey` can also generate the output as *json*. This is useful for automation.
|
||||
//!
|
||||
//! command:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey generate --output-type json
|
||||
//! ```
|
||||
//!
|
||||
//! output:
|
||||
//!
|
||||
//! ```json
|
||||
//! {
|
||||
//! "accountId": "0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515",
|
||||
//! "publicKey": "0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515",
|
||||
//! "secretPhrase": "hotel forest jar hover kite book view eight stuff angle legend defense",
|
||||
//! "secretSeed": "0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d",
|
||||
//! "ss58Address": "5Hpm9fq3W3dQgwWpAwDS2ZHKAdnk86QRCu7iX4GnmDxycrte"
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! So if you only want to get the `secretSeed` for instance, you can use:
|
||||
//!
|
||||
//! command:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey generate --output-type json | jq -r .secretSeed
|
||||
//! ```
|
||||
//!
|
||||
//! output:
|
||||
//!
|
||||
//! ```text
|
||||
//! 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
//! ```
|
||||
//!
|
||||
//! ### Additional user-defined password
|
||||
//!
|
||||
//! `subkey` supports an additional user-defined secret that will be appended to the seed. Let's see
|
||||
//! the following example:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey generate --password extra_secret
|
||||
//! ```
|
||||
//!
|
||||
//! output:
|
||||
//!
|
||||
//! ```text
|
||||
//! Secret phrase `soup lyrics media market way crouch elevator put moon useful question wide` is account:
|
||||
//! Secret seed: 0xe7cfd179d6537a676cb94bac3b5c5c9cb1550e846ac4541040d077dfbac2e7fd
|
||||
//! Public key (hex): 0xf6a233c3e1de1a2ae0486100b460b3ce3d7231ddfe9dadabbd35ab968c70905d
|
||||
//! Account ID: 0xf6a233c3e1de1a2ae0486100b460b3ce3d7231ddfe9dadabbd35ab968c70905d
|
||||
//! SS58 Address: 5He5pZpc7AJ8evPuab37vJF6KkFDqq9uDq2WXh877Qw6iaVC
|
||||
//! ```
|
||||
//!
|
||||
//! Using the `inspect` command (see more details below), we see that knowing only the **secret
|
||||
//! seed** is no longer sufficient to recover the account:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey inspect "soup lyrics media market way crouch elevator put moon useful question wide"
|
||||
//! ```
|
||||
//!
|
||||
//! which recovers the account `5Fe4sqj2K4fRuzEGvToi4KATqZfiDU7TqynjXG6PZE2dxwyh` and not
|
||||
//! `5He5pZpc7AJ8evPuab37vJF6KkFDqq9uDq2WXh877Qw6iaVC` as we expected. The additional user-defined
|
||||
//! **password** (`extra_secret` in our example) is now required to fully recover the account. Let's
|
||||
//! inspect the the previous mnemonic, this time passing also the required `password` as shown
|
||||
//! below:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey inspect --password extra_secret "soup lyrics media market way crouch elevator put moon useful question wide"
|
||||
//! ```
|
||||
//!
|
||||
//! This time, we properly recovered `5He5pZpc7AJ8evPuab37vJF6KkFDqq9uDq2WXh877Qw6iaVC`.
|
||||
//!
|
||||
//! ### Inspecting a key
|
||||
//!
|
||||
//! If you have *some data* about a key, `subkey inspect` will help you discover more information
|
||||
//! about it.
|
||||
//!
|
||||
//! If you have **secrets** that you would like to verify for instance, you can use:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey inspect < mnemonic | seed >
|
||||
//! ```
|
||||
//!
|
||||
//! If you have only **public data**, you can see a subset of the information:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey inspect --public < pubkey | address >
|
||||
//! ```
|
||||
//!
|
||||
//! **NOTE**: While you will be able to recover the secret seed from the mnemonic, the opposite is
|
||||
//! not possible.
|
||||
//!
|
||||
//! **NOTE**: For obvious reasons, the **secrets** cannot be recovered from passing **public data**
|
||||
//! such as `pubkey` or `address` as input.
|
||||
//!
|
||||
//! command:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey inspect 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
//! ```
|
||||
//!
|
||||
//! output:
|
||||
//!
|
||||
//! ```text
|
||||
//! Secret Key URI `0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d` is account:
|
||||
//! Secret seed: 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
//! Public key (hex): 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
//! Account ID: 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
//! SS58 Address: 5Hpm9fq3W3dQgwWpAwDS2ZHKAdnk86QRCu7iX4GnmDxycrte
|
||||
//! ```
|
||||
//!
|
||||
//! ### Signing
|
||||
//!
|
||||
//! `subkey` allows using a **secret key** to sign a random message. The signature can then be
|
||||
//! verified by anyone using your **public key**:
|
||||
//!
|
||||
//! ```bash
|
||||
//! echo -n <msg> | subkey sign --suri <seed|mnemonic>
|
||||
//! ```
|
||||
//!
|
||||
//! example:
|
||||
//!
|
||||
//! ```text
|
||||
//! MESSAGE=hello
|
||||
//! SURI=0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d
|
||||
//! echo -n $MESSAGE | subkey sign --suri $SURI
|
||||
//! ```
|
||||
//!
|
||||
//! output:
|
||||
//!
|
||||
//! ```text
|
||||
//! 9201af3788ad4f986b800853c79da47155f2e08fde2070d866be4c27ab060466fea0623dc2b51f4392f4c61f25381a62848dd66c5d8217fae3858e469ebd668c
|
||||
//! ```
|
||||
//!
|
||||
//! **NOTE**: Each run of the `sign` command will yield a different output. While each signature is
|
||||
//! different, they are all valid.
|
||||
//!
|
||||
//! ### Verifying a signature
|
||||
//!
|
||||
//! Given a message, a signature and an address, `subkey` can verify whether the **message** has
|
||||
//! been digitally signed by the holder (or one of the holders) of the **private key** for the given
|
||||
//! **address**:
|
||||
//!
|
||||
//! ```bash
|
||||
//! echo -n <msg> | subkey verify <sig> <address>
|
||||
//! ```
|
||||
//!
|
||||
//! example:
|
||||
//!
|
||||
//! ```bash
|
||||
//! MESSAGE=hello
|
||||
//! URI=0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515
|
||||
//! SIGNATURE=9201af3788ad4f986b800853c79da47155f2e08fde2070d866be4c27ab060466fea0623dc2b51f4392f4c61f25381a62848dd66c5d8217fae3858e469ebd668c
|
||||
//! echo -n $MESSAGE | subkey verify $SIGNATURE $URI
|
||||
//! ```
|
||||
//!
|
||||
//! output:
|
||||
//!
|
||||
//! ```text
|
||||
//! Signature verifies correctly.
|
||||
//! ```
|
||||
//!
|
||||
//! A failure looks like:
|
||||
//!
|
||||
//! ```text
|
||||
//! Error: SignatureInvalid
|
||||
//! ```
|
||||
//!
|
||||
//! ### Using the vanity generator
|
||||
//!
|
||||
//! You can use the included vanity generator to find a seed that provides an address which includes
|
||||
//! the desired pattern. Be warned, depending on your hardware this may take a while.
|
||||
//!
|
||||
//! command:
|
||||
//!
|
||||
//! ```bash
|
||||
//! subkey vanity --network pezkuwi --pattern bob
|
||||
//! ```
|
||||
//!
|
||||
//! output:
|
||||
//!
|
||||
//! ```text
|
||||
//! Generating key containing pattern 'bob'
|
||||
//! best: 190 == top: 189
|
||||
//! Secret Key URI `0x8c9a73097f235b84021a446bc2826a00c690ea0be3e0d81a84931cb4146d6691` is account:
|
||||
//! Secret seed: 0x8c9a73097f235b84021a446bc2826a00c690ea0be3e0d81a84931cb4146d6691
|
||||
//! Public key (hex): 0x1a8b32e95c1f571118ea0b84801264c3c70f823e320d099e5de31b9b1f18f843
|
||||
//! Account ID: 0x1a8b32e95c1f571118ea0b84801264c3c70f823e320d099e5de31b9b1f18f843
|
||||
//! SS58 Address: 1bobYxBPjZWRPbVo35aSwci1u5Zmq8P6J2jpa4kkudBZMqE
|
||||
//! ```
|
||||
//!
|
||||
//! `Bob` now got a nice address starting with their name:
|
||||
//! 1**bob**YxBPjZWRPbVo35aSwci1u5Zmq8P6J2jpa4kkudBZMqE.
|
||||
//!
|
||||
//! **Note**: While `Bob`, having a short name (3 chars), got a result rather quickly, it will take
|
||||
//! much longer for `Alice` who has a much longer name, thus the chances to generate a random
|
||||
//! address that contains the chain `alice` will be much smaller.
|
||||
|
||||
use clap::Parser;
|
||||
use pezsc_cli::{
|
||||
Error, GenerateCmd, GenerateKeyCmdCommon, InspectKeyCmd, InspectNodeKeyCmd, SignCmd, VanityCmd,
|
||||
VerifyCmd,
|
||||
};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(
|
||||
name = "subkey",
|
||||
author = "Parity Team <admin@parity.io>",
|
||||
about = "Utility for generating and restoring with Bizinikiwi keys",
|
||||
version
|
||||
)]
|
||||
pub enum Subkey {
|
||||
/// Generate a random node key, write it to a file or stdout and write the
|
||||
/// corresponding peer-id to stderr
|
||||
GenerateNodeKey(GenerateKeyCmdCommon),
|
||||
|
||||
/// Generate a random account
|
||||
Generate(GenerateCmd),
|
||||
|
||||
/// Gets a public key and a SS58 address from the provided Secret URI
|
||||
Inspect(InspectKeyCmd),
|
||||
|
||||
/// Load a node key from a file or stdin and print the corresponding peer-id
|
||||
InspectNodeKey(InspectNodeKeyCmd),
|
||||
|
||||
/// Sign a message, with a given (secret) key.
|
||||
Sign(SignCmd),
|
||||
|
||||
/// Generate a seed that provides a vanity address.
|
||||
Vanity(VanityCmd),
|
||||
|
||||
/// Verify a signature for a message, provided on STDIN, with a given (public or secret) key.
|
||||
Verify(VerifyCmd),
|
||||
}
|
||||
|
||||
/// Run the subkey command, given the appropriate runtime.
|
||||
pub fn run() -> Result<(), Error> {
|
||||
match Subkey::parse() {
|
||||
Subkey::GenerateNodeKey(cmd) => cmd.run(),
|
||||
Subkey::Generate(cmd) => cmd.run(),
|
||||
Subkey::Inspect(cmd) => cmd.run(),
|
||||
Subkey::InspectNodeKey(cmd) => cmd.run(),
|
||||
Subkey::Vanity(cmd) => cmd.run(),
|
||||
Subkey::Verify(cmd) => cmd.run(),
|
||||
Subkey::Sign(cmd) => cmd.run(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Subkey utility, based on kitchensink_runtime.
|
||||
|
||||
fn main() -> Result<(), pezsc_cli::Error> {
|
||||
subkey::run()
|
||||
}
|
||||
Reference in New Issue
Block a user