Subalfred

An All-In-One Substrate Development Toolbox.

License Checks Release GitHub tag (latest by date) GitHub code lines GitHub last commit

Subalfred

Philosophies

  • Lighting fast
  • Less dependencies
  • No unsafe {}, .unwrap()
  • Easy to use
  • Strive for excellence

Documentations

# Use the `--help` flag to get more information.
subalfred --help
# Each subcommand also provides its own `--help`.
subalfred check --help
subalfred check runtime --help

Contribution

Installation

There are multiple ways to install the subalfred CLI tool. Choose any one of the methods below that best suit your needs.

Pre-built Binaries

  1. Download it from the GitHub Releases page.
  2. Uncompress the downloaded file.
  3. Rename it to whatever you like. (optional)
  4. Give the execution privilege to it.

The compressing algorithm is zstd. For some systems, you might need to install zstd first. For Windows users, you would like to rename the extracted content name to subalfred.exe.

Use subalfred-aarch64-apple-darwin.zst as an example.

  • One line command:
    curl -L https://github.com/hack-ink/subalfred/releases/download/v0.9.0-rc8/subalfred-aarch64-apple-darwin.zst | zstd -o subalfred -d && chmod u+x subalfred
    
  • Multi-lines command:
    curl -LO https://github.com/hack-ink/subalfred/releases/download/v0.9.0-rc8/subalfred-aarch64-apple-darwin.zst
    zstd -o subalfred -d
    chmod u+x subalfred
    

Available pre-built binaries list.

  • subalfred-aarch64-apple-darwin.zst
  • subalfred-x86_64-apple-darwin.zst
  • subalfred-x86_64-pc-windows-msvc.zst
  • subalfred-x86_64-unknown-linux-gnu.zst

Build from Source

To build subalfred from source, you will first need to install Rust. Once you have installed Rust, the following command can be used to build and install subalfred:

  • Build from crates.io:
    cargo install subalfred
    
  • Build from the latest main branch code:
    cargo install subalfred --git https://github.com/hack-ink/subalfred
    

This will automatically download subalfred from crates.io/github.com, build it, and install it in Cargo's global binary directory (~/.cargo/bin/ by default).

The version published to crates.io will ever so slightly be behind the version hosted on github.com. If you need the latest version you can build the git version of subalfred yourself. Cargo makes this super easy!

To uninstall, run the command cargo uninstall subalfred.

Command Line Tool

The subalfred command-line tool is used to create and build books. After you have installed subalfred, you can run the subalfred help command in your terminal to view the available commands.

This following sections provide in-depth information on the different commands available.

The Check Command

Currently, there are two subcommands available.

Runtime

As the name says, the checks are on the runtime level.

There are three shared options:

  • --chain <NAME>The chain name, which will supply to the executable.
  • --executable <PATH> The executable path.
  • --live <URI> The live chain's RPC HTTP endpoint.

And there are two properties to check, storage and version.

Examples

For convenience, I use the Pangolin Network to demonstrate.

  • pangolin-dev is the dev chain spec, which means its genesis is built from the latest code. If you are on Polkadot, then use polkadot-dev.
  • ./drml is the path to my local pangolin node executable.
  • https://pangolin-rpc.darwinia.network is the Pangoro live chain's RPC HTTP endpoint. Note that, I use the Pangoro here. Just because I'm doing a demonstration. Compare with two different chains' runtime storage/version will get a lot of output.

Check Runtime Storage

subalfred check runtime --chain pangolin-dev --executable ./drml --live https://pangoro-rpc.darwinia.network --property storage
+ Pallet: "Bounties"
- Pallet: "BridgePangolinGrandpa"
- Pallet: "BridgePangolinMessages"
+ Pallet: "BridgePangolinParachainMessages"
+ Pallet: "BridgePangoroGrandpa"
+ Pallet: "BridgePangoroMessages"
+ Pallet: "BridgeRococoGrandpa"
+ Pallet: "BridgeRococoParachains"
+ Pallet: "Council"
+ Pallet: "DarwiniaEthereumRelay"
+ Pallet: "Democracy"
+ Pallet: "EcdsaRelayAuthority"
+ Pallet: "EthereumBacking"
+ Pallet: "HeaderMmr"
+ Pallet: "Identity"
+ Pallet: "Instance1DarwiniaRelayerGame"
+ Pallet: "KtonTreasury"
+ Pallet: "Multisig"
- Pallet: "PangolinFeeMarket"
+ Pallet: "PangolinParachainFeeMarket"
+ Pallet: "PangoroFeeMarket"
+ Pallet: "PhragmenElection"
+ Pallet: "Proxy"
+ Pallet: "Recovery"
+ Pallet: "Society"
- Pallet: "Substrate2SubstrateBacking"
+ Pallet: "Substrate2SubstrateIssuing"
+ Pallet: "TechnicalCommittee"
+ Pallet: "TechnicalMembership"
+ Pallet: "Tips"
+ Pallet: "ToPangolinParachainBacking"
+ Pallet: "Vesting"

Pallet ElectionProviderMultiPhase
+ Entry: StorageEntryMetadata { name: "SignedSubmissionsMap", modifier: Default, ty: Map { hashers: [Twox64Concat], key: UntrackedSymbol { id: 4, marker: PhantomData }, value: UntrackedSymbol { id: 227, marker: PhantomData } }, default: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], docs: [" Unchecked, signed solutions.", "", " Together with `SubmissionIndices`, this stores a bounded set of `SignedSubmissions` while", " allowing us to keep only a single one in memory at a time.", "", " Twox note: the key of the map is an auto-incrementing index which users cannot inspect or", " affect; we shouldn't need a cryptographically secure hasher."] }
- Entry: StorageEntryMetadata { name: "SignedSubmissionsMap", modifier: Default, ty: Map { hashers: [Twox64Concat], key: UntrackedSymbol { id: 4, marker: PhantomData }, value: UntrackedSymbol { id: 186, marker: PhantomData } }, default: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], docs: [" Unchecked, signed solutions.", "", " Together with `SubmissionIndices`, this stores a bounded set of `SignedSubmissions` while", " allowing us to keep only a single one in memory at a time.", "", " Twox note: the key of the map is an auto-incrementing index which users cannot inspect or", " affect; we shouldn't need a cryptographically secure hasher."] }

Pallet Scheduler
+ Entry: StorageEntryMetadata { name: "Agenda", modifier: Default, ty: Map { hashers: [Twox64Concat], key: UntrackedSymbol { id: 4, marker: PhantomData }, value: UntrackedSymbol { id: 609, marker: PhantomData } }, default: [0], docs: [" Items to be executed, indexed by the block number that they should be executed on."] }
- Entry: StorageEntryMetadata { name: "Agenda", modifier: Default, ty: Map { hashers: [Twox64Concat], key: UntrackedSymbol { id: 4, marker: PhantomData }, value: UntrackedSymbol { id: 378, marker: PhantomData } }, default: [0], docs: [" Items to be executed, indexed by the block number that they should be executed on."] }

Pallet Session
+ Entry: StorageEntryMetadata { name: "NextKeys", modifier: Optional, ty: Map { hashers: [Twox64Concat], key: UntrackedSymbol { id: 0, marker: PhantomData }, value: UntrackedSymbol { id: 347, marker: PhantomData } }, default: [0], docs: [" The next session keys for a validator."] }
- Entry: StorageEntryMetadata { name: "NextKeys", modifier: Optional, ty: Map { hashers: [Twox64Concat], key: UntrackedSymbol { id: 0, marker: PhantomData }, value: UntrackedSymbol { id: 282, marker: PhantomData } }, default: [0], docs: [" The next session keys for a validator."] }
+ Entry: StorageEntryMetadata { name: "QueuedKeys", modifier: Default, ty: Plain(UntrackedSymbol { id: 345, marker: PhantomData }), default: [0], docs: [" The queued keys for the next session. When the next session begins, these keys", " will be used to determine the validator's session keys."] }
- Entry: StorageEntryMetadata { name: "QueuedKeys", modifier: Default, ty: Plain(UntrackedSymbol { id: 280, marker: PhantomData }), default: [0], docs: [" The queued keys for the next session. When the next session begins, these keys", " will be used to determine the validator's session keys."] }

Pallet System
+ Entry: StorageEntryMetadata { name: "Events", modifier: Default, ty: Plain(UntrackedSymbol { id: 15, marker: PhantomData }), default: [0], docs: [" Events deposited for the current block.", "", " NOTE: This storage item is explicitly unbounded since it is never intended to be read", " from within the runtime."] }
- Entry: StorageEntryMetadata { name: "Events", modifier: Default, ty: Plain(UntrackedSymbol { id: 15, marker: PhantomData }), default: [0], docs: [" Events deposited for the current block.", "", " NOTE: This storage item is explicitly unbounded since it is never intended to be read", " from within the runtime."] }

Check Runtime Version

subalfred check runtime --chain pangolin-dev --executable ./drml --live https://pangoro-rpc.darwinia.network --property version
RuntimeVersion {
-   spec_name: "Pangoro",
+   spec_name: "Pangolin",
-   impl_name: "Pangoro",
+   impl_name: "Pangolin",
    authoring_version: 0,
    spec_version: 29020,
    impl_version: 0,
    transaction_version: 0,
}

STD Feature

As we know Substrate have two runtime ENVs, native and WASM.

If a runtime dependency is not pure no-std, we need to write:

[features]
std = ["xxx/std"]

[dependencies]
xxx = { version = "0.1.0", default-features = false }

Sometimes, we might forget to write add the xxx/std. Recently, I found someone have the same requirement. So, I decide to make this public.

Examples

git clone https://github.com/paritytech/frontier /tmp/paritytech/frontier
subalfred check std-feature --manifest-path /tmp/paritytech/frontier/Cargo.toml
`fp-evm`'s std feature was disabled in `/tmp/paritytech/frontier/primitives/ethereum/Cargo.toml`
`ed25519-dalek`'s std feature was disabled in `/tmp/paritytech/frontier/frame/evm/precompile/ed25519/Cargo.toml`
`bn`'s std feature was disabled in `/tmp/paritytech/frontier/frame/evm/precompile/bn128/Cargo.toml`
`curve25519-dalek`'s std feature was disabled in `/tmp/paritytech/frontier/frame/evm/precompile/curve25519/Cargo.toml`
`frame-benchmarking`'s std feature was disabled in `/tmp/paritytech/frontier/template/runtime/Cargo.toml`
`frame-system-benchmarking`'s std feature was disabled in `/tmp/paritytech/frontier/template/runtime/Cargo.toml`

CI

Moreover, we can add the checks into your project CI.

I've already add these to the Darwinia CI. And here is a real world example.

The Convert Command

A set of really useful convertors.

Ascii to Hex

Convert the ascii to hex.

Examples

subalfred convert ascii2hex AurevoirXavier
0x41757265766f6972586176696572

Bytes Style

Convert the bytes between several different styles.

Examples

From Vec String to Byte String Literal

subalfred convert bytes-style --from vec-string --to byte-string-literal "[65, 117, 114, 101, 118, 111, 105, 114, 88, 97, 118, 105, 101, 114]"
AurevoirXavier
subalfred convert bytes-style --from vec-string --to byte-string-literal "[1, 1, 1, 1]"
\x01\x01\x01\x01

From Byte String Literal to Vec String

subalfred convert bytes-style --from byte-string-literal --to vec-string "AurevoirXavier"
[65, 117, 114, 101, 118, 111, 105, 114, 88, 97, 118, 105, 101, 114]
subalfred convert bytes-style --from byte-string-literal --to vec-string "\x01\x01\x01\x01"
[1, 1, 1, 1]

Bytes to Hex

Convert the bytes to hex.

Examples

subalfred convert bytes2hex "[65, 117, 114, 101, 118, 111, 105, 114, 88, 97, 118, 105, 101, 114]"
0x41757265766f6972586176696572

Hex to Bytes

Convert the hex to bytes.

Examples

subalfred convert hex2bytes 0x41757265766f6972586176696572
[65, 117, 114, 101, 118, 111, 105, 114, 88, 97, 118, 105, 101, 114]

The Get Command

Currently, there only one subcommand available.

Runtime Upgrade Block

The origin question is from stackexchange.

Yep, I think that is an interesting question. So, I implemented this method.

It uses dichotomy algorithm, the whole process takes times requests.

Examples

subalfred get runtime-upgrade-block 9100 --uri wss://rpc.polkadot.io -lsubalfred::core::node
2022-08-27T13:58:07.684200Z TRACE subalfred::core::node: (0, 11788056) -> 9050
2022-08-27T13:58:09.469688Z TRACE subalfred::core::node: (5894028, 11788056) -> 9151
2022-08-27T13:58:10.874493Z TRACE subalfred::core::node: (5894028, 8841042) -> 9110
2022-08-27T13:58:11.852626Z TRACE subalfred::core::node: (5894028, 7367535) -> 9080
2022-08-27T13:58:12.916960Z TRACE subalfred::core::node: (6630782, 7367535) -> 9090
2022-08-27T13:58:13.126836Z TRACE subalfred::core::node: (6999158, 7367535) -> 9090
2022-08-27T13:58:14.591213Z TRACE subalfred::core::node: (7183346, 7367535) -> 9110
2022-08-27T13:58:14.800144Z TRACE subalfred::core::node: (7183346, 7275440) -> 9110
2022-08-27T13:58:15.921005Z TRACE subalfred::core::node: (7183346, 7229393) -> 9090
2022-08-27T13:58:18.036717Z TRACE subalfred::core::node: (7206370, 7229393) -> 9090
2022-08-27T13:58:18.993673Z TRACE subalfred::core::node: (7217881, 7229393) -> 9100
2022-08-27T13:58:19.208425Z TRACE subalfred::core::node: (7217881, 7223637) -> 9100
2022-08-27T13:58:19.415621Z TRACE subalfred::core::node: (7217881, 7220759) -> 9100
2022-08-27T13:58:19.624220Z TRACE subalfred::core::node: (7217881, 7219320) -> 9100
2022-08-27T13:58:19.828821Z TRACE subalfred::core::node: (7217881, 7218601) -> 9100
2022-08-27T13:58:20.035127Z TRACE subalfred::core::node: (7217881, 7218241) -> 9100
2022-08-27T13:58:20.240336Z TRACE subalfred::core::node: (7217881, 7218061) -> 9100
2022-08-27T13:58:20.444889Z TRACE subalfred::core::node: (7217881, 7217971) -> 9100
2022-08-27T13:58:21.594894Z TRACE subalfred::core::node: (7217881, 7217926) -> 9090
2022-08-27T13:58:24.625042Z TRACE subalfred::core::node: (7217904, 7217926) -> 9100
2022-08-27T13:58:24.824345Z TRACE subalfred::core::node: (7217904, 7217915) -> 9100
2022-08-27T13:58:25.030852Z TRACE subalfred::core::node: (7217904, 7217910) -> 9100
2022-08-27T13:58:26.058492Z TRACE subalfred::core::node: (7217904, 7217907) -> 9090
2022-08-27T13:58:26.275470Z TRACE subalfred::core::node: (7217906, 7217907) -> 9090
7217907 0x8f10de9e6dcf190dccc90f464a8aa4448c9b080746d8e905bb0e4841fef80fdd

The Hash Command

Hash the data with the specify algorithm.

Available algorithms:

  • blake2-128
  • blake2-128-concat (default)
  • blake2-256
  • blake2-512
  • twox64
  • twox64-concat
  • twox128
  • twox256
  • keccak256
  • keccak512
  • sha2-256

Examples

blake2-128-concat (Default)

subalfred hash 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0xe58b08eb4646f23e89bde2676c8e1feeb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747

blake2-128

subalfred hash --hasher blake2-128 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0xe58b08eb4646f23e89bde2676c8e1fee

blake2-256

subalfred hash --hasher blake2-256 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0x83aa9248019a972a674ada58cfcb6b0dc85cc94c90691b1e93d3e71ded507d32

blake2-512

subalfred hash --hasher blake2-512 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0x7068368532a7b4a4dedf9994bfe584e4479304e8db003cee3658db7ad938add4ab2ce8d62e559e4de141227124d3b5b1d8d84d3e5e56084ea7804f871b3fde9d

twox64

subalfred hash --hasher twox64 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0x3ab053dc6b6a71e1

twox64-concat

subalfred hash --hasher twox64-concat 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0x3ab053dc6b6a71e1b4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747

twox128

subalfred hash --hasher twox128 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0x3ab053dc6b6a71e13f13e44949b8e388

twox256

subalfred hash --hasher twox256 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0x3ab053dc6b6a71e13f13e44949b8e388638838f880a0e3dc18e197b7f8efd6dc

keccak256

subalfred hash --hasher keccak256 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0x7774e3a14e4868bd5f3f6bd409685efd0e5179e783ed53d2a5da42c911efb05a

keccak512

subalfred hash --hasher keccak512 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0xe7aeb316f9808098e7d71998d4642c784aecbdbbc03061fdcaec6992831bf6ae5abb5673af4f3dec4f4aeed543390ffeda9e0f8900f771f56043128177b1bcea

sha2-256

subalfred hash --hasher sha2-256 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
0x5d0ae9ab625ce7c50e5ced079f414f28161b1b645df49679ebd794fc43c239bc

The Key Command

Convert the public key/SS58 address from SS58 address/public key.

Examples

Get the Public Key

subalfred key 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
public-key 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
Substrate 5G9z8Ttoo7892VqBHiSWCbnd2aEdH8noJLqZ4HFMzMVNhvgP

Get the SS58 Address

subalfred key 5G9z8Ttoo7892VqBHiSWCbnd2aEdH8noJLqZ4HFMzMVNhvgP
public-key 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
Substrate 5G9z8Ttoo7892VqBHiSWCbnd2aEdH8noJLqZ4HFMzMVNhvgP

Get the Pallet Address

subalfred key --type pallet "py/trsry"
public-key 0x6d6f646c70792f74727372790000000000000000000000000000000000000000 PalletId(py/trsry)
Substrate 5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

Subalfred will detect if this is a pallet address automatically.

subalfred key 5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z
public-key 0x6d6f646c70792f74727372790000000000000000000000000000000000000000 PalletId(py/trsry)
Substrate 5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

Get the Sovereign Address

Sovereign address on relaychain.

subalfred key --type parachain 2000
public-key 0x70617261d0070000000000000000000000000000000000000000000000000000 ParaId(2000)
Substrate 5Ec4AhPUwPeyTFyuhGuBbD224mY85LKLMSqSSo33JYWCazU4

Sovereign address on sibling chain.

subalfred key --type sibling 2000
public-key 0x7369626cd0070000000000000000000000000000000000000000000000000000 SiblId(2000)
Substrate 5Eg2fntJ27qsari4FGrGhrMqKFDRnkNSR6UshkZYBGXmSuC8

Note that, if you are on Moonbeam-link chain, remove 24 trailing zeros from the public-key.

public-key 0x7369626cd0070000000000000000000000000000000000000000000000000000 SiblId(2000)
public-key 0x7369626cd0070000000000000000000000000000 SiblId(2000)

Subalfred will detect if this is a sovereign address automatically.

subalfred key 5Eg2fntJ27qsari4FGrGhrMqKFDRnkNSR6UshkZYBGXmSuC8
public-key 0x7369626cd0070000000000000000000000000000000000000000000000000000 SiblId(2000)
Substrate 5Eg2fntJ27qsari4FGrGhrMqKFDRnkNSR6UshkZYBGXmSuC8

Options

These flags can be applied to any key command. Also, they could be used with any other flags.

List All

subalfred key --list-all 5G9z8Ttoo7892VqBHiSWCbnd2aEdH8noJLqZ4HFMzMVNhvgP
public-key 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
BareEd25519           NTG3mn5om1nwD45xx8aUTR3pefA8zEVwfES4dAcw1JMjNgm
BareSecp256k1         5MwePTSDBPzsBZEeCFKXaW43g4NvLKRKVHPgfxtfTD5rzTug
BareSr25519           AswXnhH3BGLd6FA9tNXietCXgNa2cyTZn8AqFt21J7PAnpZ
DICO                  6MpEyNrF2Jk8k9HHFa7mMWiJ8uort9iXNgvzpoKg5m2jonV1
Eggnet                oVRYSJ9KxJzim3FzSpeAMPBJpmQYP6wkEkHz5erKyhFmc3PUL
ICE                   npQjXEEdK3EkZyJp4gUC4jqKg4gdQeHYizXNk6bsFevGx1Dos
KICO                  6G2aiPJqe1sQb5spM3EjycSsVRfZpy61BkNsD7gNcuSFXSgN
SNOW                  ni2MJgjyWScn3yYvNiPtYaAJUhdUb8ZFQvKvLirhz2CDjzTtu
Turing                cU8jCBoMnvw9xNB3HoVoB4bPFwaLQTjVSBxarreqv8m5UubMC
acala                 24xsriZuVo8t2ctLJgHk7mH2M3fDXGe9GF7MNQfjAzTmhcR3
ajuna                 aUtUKdw182tzTyNnVgZijvnDTU9An54EGKajDGD3AM9JHr8Ci
altair                kAMF48Seoe2NLpgBpERuPiUhaBVqPuKM5kG22BGtNkgC5UF25
amplitude             6kxt1M1rZUF3NNu8shdrs7mzirP36tEc8T9XHXtswBQgvnbM
apex                  rzg96q3EEBeHKBq4PoA9jZo3RGoqMuGNUzGTXt9NHs3zsKZNg
ares                  4Tri4XZain8Kn2bU3TQKBPfDrh6GqfkdnpQW8p6xHWjUTQsr
astar                 a2aZkrtaLmFFKs1n1tdEFwu7cwkFMVYKYLhHzTDriVLJ5GZ
aventus               cLx3haNNmFzBd7wutbATTsiEfQe3EWY9xcEhQZSYEoCGNeAUs
bajun                 bUMvGXNsMQUm7wBohPESRRqQDjdY9gcv4yMpqduUb3fo9xRzt
basilisk              bXkghK7H4UNVqFBZUBLMEGUSfi8Q9YrKmPLfJZ9Lpnk1jXLSg
bifrost               fpEpkQHxddyQPGUgYmecADKm763JY84WUtpug6XKa5paJMM
calamari              dmy2WdnrD23rM4nVrA8PE3TWD8M1tB231YoceS7ck2cz4nvbM
centrifuge            4fS2aWePVMsn69QPrXAMwCC59fNrx31gAhWmNBPZDDvT24fC
cere                  6TbuENPeQbcruCgkA6znjQyinPx9wLM3ZdV8SUxyYcdE61cs
cess                  ce7TA31W7N2cdz3VgNjmYphyka6dox4TV41yzP1A2SGYF3pYk
cess-testnet          cXj4wVWrJmQe7zHbzQfU2f2xZD3UzSLAAypXb1FzkoYV32xMV
chainflip             cFMxm6p4BjhCvNfFusMC8jFLsDU2mSGtp3Zg47AXNsJy4tDoM
chainx                5TjJeSycZgsbLce76nCYxQKUKYXDPW3qgDwpHeXxv4gMGnqJ
clover                jHGBKnVSNs4aCrd4JVqVEP6Y1H4cqoUxbAgNoBKcDgskRNmg8
composable            64TGCQE2sS7xGy4tXyUhDov2CTNyibpxosGbykPmhCFGxk6n
contextfree           a7SDW4dbSQLxCPkokx6adk336WpRZGerMmMcyzFmRoJTTLqrd
cord                  3xvQmZrZoKkgzja9Wo1CHtL6dGNoZkc2r7dr4PtSyEm342uB
crust                 cTLRv7s2ZrcA97hoaZEkz3PFrmhC42GTGgS9owBhWRvKaexfe
dark                  2mUVffMjBqFy82iaeQSum58zsSfGuZ3napzGgCAqQydBg7vY
darwinia              2sG9veu8a88hH683YwKw8yQRWvoZxjgJmmYQHsp8sqDfxHHW
datahighway           4N53oY2BLVFbcyC18vXHoVPoDCwynV87bsrNX8Tepf8zBJfV
dentnet               dx9Knzz5LDj4UzmmAYS7eZNdZ3qbsmiG6nk83BqDTFqdoVwGm
dock-pos-mainnet      3GQnxd4k7HdbuKjuB4r2eaU86sNkBUCPXXkvkcPLjFbd5YU5
edgeware              mbu5jwhLvWhZSfwb5efz4UkQbELMikahRSxXMjpnRgJrcEc
efinity               efTEt1iEFLB9Pf5FDWrKUtSjUciocVawat9UPtoU6wqog1dGD
equilibrium           cg7CMCrLB3r7B7DaxVPN2NjJFVoVh3j3tpq4cgg23hNRzgFAa
fragnova              fRkmknCdFyMU718sBfEv2YYp9aAJArxWgdmSh4H1nXVpAy4qJ
geek                  XWGZATcKd9Zw3mpuxmVoefp8KNhn57zuozNL4ukSHKrciyPew
genshiro              cZip8fMgNTE8f7ThGXK4WD4H48kLsXzkakdcDJvrn4eNnfXNT
gm                    gMY6J6wTa8AssBmvDrD5q5GABvhNfSjuEJk3Tfgf56PJzfGj3
heiko                 hJKHS1bhv7u2tw11u6W3sNzAUk5t6aMays8BYRvjNHpkhAqHG
hydradx               7MgqZJGGsDVQJjKvJtv18XNYbmEoRz1jG6UJydkgiJyccwqp
integritee            2NKrdhC7efm4Vo6j2GvpFU5JHW66gpXhq4mkDTbdZZFEYdqE
integritee-incognito  hdUS5e5fKukxSvGgxzixRt1E4qFLZ7YUv5iYkZADBBzvKCfaw
interlay              wdBbAQmEBQZqDUnhj7sUehkhvTYeebSo8bPErUT1Wr572f6YH
joystream             j4VQthW8mfpdAs7GvZgtC3kVcYxKCn2My2HTzRqHgRRe1MgG8
jupiter               3fZRzbEMeT8WXZMkoCN8ABXpgowvQCiUHHyTDLxYafyaCmYh
kabocha               3mM6Famm2k1EgcmDhjF9Y5oFLJ6DTPLzUEXaq2br3Xa4VG9o
kapex                 tsY1kqQw6V4UHasRVx1veXwC2PBrAnDLLnSrn6r1n1wirN28x
karura                sPZLjV6jDPRiW5QVcXhMxkB45NdQuP6tN1693P8FHGo8zCJ
katalchain            UEvJmKVC3tX6GTYsV1brMgUU8oTCAs28bnZgJovPrtr1t9S
kilt                  4s1M6VjCFwdEQGDKfavQgzivSdfT4QGiYad2bYgA8w7RauZQ
kintsugi              a3eJSEw27oHiaTXS8Xs9jPnvwxNzPBgvabcZzcHKzCorveaqE
kulupu                2fgqQfpKoYPExyK7jsZtPAsaDxWyrNRGPtS94WXXx82hPqRq
kusama                GfbnnEgRU94n9ed4RFZ6Z9dBAWs5obykigJSwXKU9hsT2uU
laminar               2AkY7i7Jt61cBgHoDDAmVfYSzXoWaTGfTBfUz6K2dr4FyzaL
litentry              4AVjHYwNZuW9JrP5KrmF3grwvEfPg7s5Dzk7HmB3twx1cPDT
litmus                jcRKyQyPnevVkqtjNQ4Pnt7bbNE5JLfrXPGk1JZ62b3v3R4u2
manta                 dfaeJ6JCQRRsq52cAC45hsnV1mHs4fHjhUcAF4NTUPtvrnT4s
mathchain             4xo1MVGbeEVxZKcna7oS4tzM67ok7auEjXBADEKTbnhurwn7
mathchain-testnet     54afcUp12XNgiP2FUegTSoFmjbx3AmXkvTjHpuxm4eJQ9WvS
moonbeam              VducokCKmmc7iA5aB9JRrbBJqVkUjWy6Z8thUmU1JVEsBLJ47
moonriver             VkJ12HgyaNE6E9qTs7NjNkrL2rodZ2hPsD69t9DAa7xvPM3Ah
neatcoin              5rswgR9E6rNVxrFxiuieU1PAuV6PcEZvRzALkP7AmV4JPvtN
nftmart               nmv42mS6ERxtQ4qhU3ACUJJg3uZ44GhoiH1XTiWnj5YQky5bG
nodle                 4mDgqWBnsekWFCorm43PK6TVo9XA1DeCMe4tys2rg5WwJUjp
oak                   6AEvTPmSFizgS2UMSWMibiBSqwXGmnTUzopjbS35A3qmF5bR
origintrail-parachain gJqqV89qgkKGEyBzhPqLBsvyiUbWixnuBDM5v4EHwbJFq4Z7Z
p3d                   d1GLzqLHaqi2j6VG2PcGaskMqaxx9auwq3RRpouVrbYbciRnp
p3dt                  d7ejDNpwPSL1F6F9iMga73RP2x26y6eF97ctEBef8EGepiwZK
parallel              p8F2qgE7j8MSxfvGd36n7ihSdFTJtMa6JMNQXg4e5YnBXtbnX
peaq                  rtHktHYaRb2JoC5Ahq5rDQ82DukgYPY5Av518WQD2EKwfJtzL
pendulum              6fBDkMUTBBNKDKVfyAkqVDWa5NEk3hc5wWbPfrFaUKpCeWGr
phala                 44i52ZPyBcdR9nycRKtDfnbXGkX6cwEZ34Byg5XkS6MXL68i
picasso               5xfbwQgdV9FE7ufRdSbfquebYyEgfRCScviUN4kUELengQY6
pioneer_network       WWbXu4BNb1QQwVu5qFmKvQxQhpF87Q4xxxi8BJgiFhcvtJhmy
poli                  5ANKsUMQQpFQsSRiPBZUphXCP66LDxAH7QHRSbc4XVttRfvK
polkadex              esprg4jNEzFbX2MQjpsQRiBiAktY5JK28GnAgBZDSMsY8uq69
polkadexparachain     ezDEtcE23asa327JRnwhwsrjN7wgtp3KSLyd5ZJNhzbbLvKwY
polkadot              156HGo9setPcU2qhFMVWLkcmtCEGySLwNqa3DaEiYSWtte4Y
polkafoundry          g65543AY5Z5KCygDKTgj9YawKkVD5wLJZ4xB7JjyQKr9R3Dz3
polkasmith            fyggqVftGxTLgyvKdVcRdNuv8PS4GRc1Ezkihvzp8h86D2Yxp
polymesh              2GYCNheiGNtLLjhG7k3nsZose1wodduBe8DcbmxL6hekGSn8
pontem-network        gkPNMJ8Su8oAJxDZTG8YGYd4Vvp811i6RW8uXZCw28CUf7N6c
quartz_mainnet        yGGpnkEDQfqKtKjEpHFrHZY9tNxvsu6sAMmBynpuT6xmis9QJ
reserved46            5fJdAS4RLGd3ejT2uqxbiCrKcWooVsJt4745X1pZqmsKqDd7
reserved47            5m6HRRbpiZVmonrVpNqd677kFzx6Z3wQF3cD8hTsJdTp7q5Q
reynolds              yBDbj2W7WG9sZUsQ9Qijs1bhZWvU61d5JZDkj2Ri8sHRFbo
robonomics            4GHPYYUmxCNsTunYEPeGRb8NZiogjJVbQwJEuSpMMoYVtpSv
sapphire_mainnet      pxLUnGR64Nb1HxDGDbioZj3dSmLEcoubBGjRpDWdCivnZYW8r
shift                 3NCTDcc9VaWL4P9N5bj42UjYkMX3EepuiUK4NJ2eC7C7MwEw
social-network        xw7g97kFzsyQLLTZkP2wj4X6JHoURMuyE9ApmfbReCnc6q2BN
sora                  cnVaZkLyyeU5h6yUeTTfYYQKSrreWZTMCu2X24RBKL6VCh161
sora_kusama_para      oFFkmbGShjgXYrvYaD3EymDYUzWEdJvLKxjKSHo1DwqLN5eiM
stafi                 34qUSdywLht9bCvyN15ytmwGou6A56wM9eefXF6joYQeWpZG
subsocial             3s8kWaKAR2sxqgAgcG8Auz4fynEWWZyWfB5iSiF9WPAYmTxu
subspace              sufAN5qjKG8hG7zsijsHM5JG4TTmW3ais9idFa5sAj6jnm9Cg
subspace_testnet      stAMUCxcGVmaMn7om9t5zQnGgmBd6DqH4KcKHLqDenGpUYRFG
substrate             5G9z8Ttoo7892VqBHiSWCbnd2aEdH8noJLqZ4HFMzMVNhvgP
synesthesia           2ZuB9gGvRFWWouueqLgs1Gc9aUNgoBnkCwt1SptEVGSD7FJ6
tidefi                fhDnzqyYkYT2mDEa63mGi5E31kNTkNN7MsZK3RDhTJ2ykbHKr
tinker                i51xwp4GYJErWuJFis2AWYhJrHTwqATgANWNN48rFiu99FPRH
totem                 2U7WtgjX2xdnerWBvooqdNLivzEPk1AE21Ksq9Ew2Qqiq2f9
uniarts               5ZWxuSX1wykKVg3a1K5aLJaty2fWSggMsAVwuLBGNvGqZAkM
unique_mainnet        unicLcCWzL8dgqA3khnpJoEwWrp4u2twmKn8m29oFohekNWVg
vln                   4ZeNKX6z7513w5zvwzHLZHveWBEZtrP9ykxdkVkFkNKxjh7r
xxnetwork             6ZPZVMw3ntVb4G6D4dsp7KF9Rt6SzWyZka3G4AcH1UDiNL2o
zeitgeist             dE37RvKbC2wym613QKksdD6QEK5FncNYTBpLdZPpPrzi2jYtt
zero                  3Tz7Uc9YssP4DSYpz8c5QNzyPqfLHqTRuQsByyfwexnbeM1M
zero-alphaville       3ZmmjbgxGAFnNVxHtfV6nHGQ3KodM25x6MRKbfKF7pP5vUpv

Network

The network parameter is case insensitive.

subalfred key --network polkadot 5G9z8Ttoo7892VqBHiSWCbnd2aEdH8noJLqZ4HFMzMVNhvgP
public-key 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
polkadot 156HGo9setPcU2qhFMVWLkcmtCEGySLwNqa3DaEiYSWtte4Y

Show Prefix

subalfred key --show-prefix 5G9z8Ttoo7892VqBHiSWCbnd2aEdH8noJLqZ4HFMzMVNhvgP
public-key 0xb4f7f03bebc56ebe96bc52ea5ed3159d45a0ce3a8d7f082983c33ef133274747
Substrate 42 5G9z8Ttoo7892VqBHiSWCbnd2aEdH8noJLqZ4HFMzMVNhvgP

Type

See Get the Pallet Address and Get the Sovereign Address sections.

The State Command

Provides a series of useful state operations.

Diff

Get the differences between the two given states.

In fact, it accepts two chain spec files. So, make sure JSON file contains the object["genesis"]["raw"]["top] field.

Note that, this is not a symmetric diff. a.diff(b) may equals to b.diff(a), but not always.

Examples

subalfred state diff a.json b.json
-0xbd2a529379475088d3e29a918cd47872878d434d6125b40443fe11fd292d13a4:0x03000000
-0x4d45a146e2a002ba470f48b9ed9a3e23878d434d6125b40443fe11fd292d13a4:0x02000200
-0xcebf674407db61a30e8759ec5084b7764e7b9012096b41c4eb3aaf947f6ea429:0x0000
-0x2f85f1e1378cb2d7b83adbaf0b5869c24e7b9012096b41c4eb3aaf947f6ea429:0x0000
-0x4a0fb74e77bb0a3a5a6c24785f9805fe878d434d6125b40443fe11fd292d13a4:0x02000500
-0x2aa79c02f5980c623c5a8c28e06320c4878d434d6125b40443fe11fd292d13a4:0x02000200

subalfred state diff b.json a.json
+0xbd2a529379475088d3e29a918cd47872878d434d6125b40443fe11fd292d13a4:0x03000000
+0x4d45a146e2a002ba470f48b9ed9a3e23878d434d6125b40443fe11fd292d13a4:0x02000200
+0xcebf674407db61a30e8759ec5084b7764e7b9012096b41c4eb3aaf947f6ea429:0x0000
+0x2f85f1e1378cb2d7b83adbaf0b5869c24e7b9012096b41c4eb3aaf947f6ea429:0x0000
+0x4a0fb74e77bb0a3a5a6c24785f9805fe878d434d6125b40443fe11fd292d13a4:0x02000500
+0x2aa79c02f5980c623c5a8c28e06320c4878d434d6125b40443fe11fd292d13a4:0x02000200

Export

Export the chain state from a live chain.

The result will be store at <a>.export.

Examples

For convenience, I use the Darwinia Network to demonstrate.

Here is a most common way to use this command. To build a fork-off chain:

# If you want to renew the consensus you need to provide a genesis to override the exported consensus state.
# Otherwise, you can not get the old validators online. And the new chain will be bricked.
darwinia build-spec --raw > darwinia-dev.json
# `--simple-governance` will simplify the the governance state for more detail check the `--help`.
# If some pallets state are too large, you could skip them with this flag: `--skip-pallets System,Staking,Scheduler`.
subalfred state export wss://rpc.darwinia.network --renew-consensus-with darwinia-dev.json --simple-governance --disable-default-bootnodes -lsubalfred::core::node,subalfred::core::substrate_client
2022-08-27T17:30:15.077768Z TRACE subalfred::core::substrate_client: fetched 512 keys
2022-08-27T17:30:15.103602Z TRACE subalfred::core::substrate_client: fetched 1024 keys
...
✓ fully exported 152674 pairs, takes 7s

To run the fork-off chain:

darwinia --chain darwinia-dev.json.export --alice --tmp
2022-08-25 15:31:45   _____                      _       _
2022-08-25 15:31:45  |  __ \                    (_)     (_)
2022-08-25 15:31:45  | |  | | __ _ _ ____      ___ _ __  _  __ _
2022-08-25 15:31:45  | |  | |/ _` | '__\ \ /\ / / | '_ \| |/ _` |
2022-08-25 15:31:45  | |__| | (_| | |   \ V  V /| | | | | | (_| |
2022-08-25 15:31:45  |_____/ \__,_|_|    \_/\_/ |_|_| |_|_|\__,_|
2022-08-25 15:31:45 Darwinia
2022-08-25 15:31:45 ✌️  version 0.12.3-2-unknown-x86_64-linux-gnu
2022-08-25 15:31:45 ❤️  by Darwinia Network <hello@darwinia.network>, 2018-2022
2022-08-25 15:31:45 📋 Chain specification: Darwinia Development Testnet-export
2022-08-25 15:31:45 🏷 Node name: Alice
2022-08-25 15:31:45 👤 Role: AUTHORITY
2022-08-25 15:31:45 💾 Database: RocksDb at /tmp/substrateVfPtI4/chains/darwinia_dev-export/db/full
2022-08-25 15:31:45 ⛓  Native runtime: Darwinia-1232 (Darwinia-0.tx0.au0)
2022-08-25 15:32:15 🔨 Initializing Genesis block/state (state: 0xfff2…5f26, header-hash: 0xa524…c2b5)
2022-08-25 15:32:15 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
2022-08-25 15:32:16 ⏱  Loaded block-time = 6s from block 0xa524d767208b0142b2e2515f072add8391eb8d46359592f385585b453034c2b5
2022-08-25 15:32:16 👶 Creating empty BABE epoch changes on what appears to be first startup.
2022-08-25 15:32:16 🏷 Local node identity is: 12D3KooWBZ5yN77nLrmca1E7Fu1DpgXR5Y9VK3xupwPsWQHDBcdQ
2022-08-25 15:32:16 DVM mapping worker starts syncing from 0
2022-08-25 15:32:16 📦 Highest known block at #0
2022-08-25 15:32:16 〽️ Prometheus exporter started at 127.0.0.1:9615
2022-08-25 15:32:16 Listening for new connections on 0.0.0.0:9944.
2022-08-25 15:32:16 👶 Starting BABE Authorship worker
2022-08-25 15:32:18 🙌 Starting consensus session on top of parent 0xa524d767208b0142b2e2515f072add8391eb8d46359592f385585b453034c2b5
2022-08-25 15:32:18 🎁 Prepared block for proposing at 1 [hash: 0x7b730198ec586071afc14498afa6c1a1f94353db0008e427758adb6353a05690; parent_hash: 0xa524…c2b5; extrinsics (1): [0x60ef…54c4]]
2022-08-25 15:32:18 🔖 Pre-sealed block for proposal at 1. Hash now 0x9a763a5d33bd5bbb7fb37cb5fab5c8ec4f7c05f9e6cc4c1710a6d5076973c3e9, previously 0x7b730198ec586071afc14498afa6c1a1f94353db0008e427758adb6353a05690.
2022-08-25 15:32:18 👶 New epoch 0 launching at block 0x9a76…c3e9 (block slot 276902123 >= start slot 276902123).
2022-08-25 15:32:18 👶 Next epoch starts at slot 276904523
2022-08-25 15:32:18 ✨ Imported #1 (0x9a76…c3e9)
2022-08-25 15:32:21 💤 Idle (0 peers), best: #1 (0x9a76…c3e9), finalized #0 (0xa524…c2b5), ⬇ 0 ⬆ 0
2022-08-25 15:32:24 🙌 Starting consensus session on top of parent 0x9a763a5d33bd5bbb7fb37cb5fab5c8ec4f7c05f9e6cc4c1710a6d5076973c3e9
2022-08-25 15:32:24 🎁 Prepared block for proposing at 2 [hash: 0xfe20a319a55f621fcb5c0a7a93679931a3e729a90836cac71ac47e23475db69a; parent_hash: 0x9a76…c3e9; extrinsics (1): [0xcb64…465b]]
2022-08-25 15:32:24 🔖 Pre-sealed block for proposal at 2. Hash now 0x60275c406bd17b9c2ea4fd25a459db4fd5e3d0b46e5f4134789927b8cbe4c86e, previously 0xfe20a319a55f621fcb5c0a7a93679931a3e729a90836cac71ac47e23475db69a.
2022-08-25 15:32:24 ✨ Imported #2 (0x6027…c86e)
2022-08-25 15:32:26 💤 Idle (0 peers), best: #2 (0x6027…c86e), finalized #0 (0xa524…c2b5), ⬇ 14 B/s ⬆ 0
2022-08-25 15:32:30 🙌 Starting consensus session on top of parent 0x60275c406bd17b9c2ea4fd25a459db4fd5e3d0b46e5f4134789927b8cbe4c86e
2022-08-25 15:32:30 🎁 Prepared block for proposing at 3 [hash: 0x47a99410fa4b2414e1a50198ecd6f7ba191e3089942f29a3144bd0f37d48af53; parent_hash: 0x6027…c86e; extrinsics (1): [0xa820…1274]]
2022-08-25 15:32:30 🔖 Pre-sealed block for proposal at 3. Hash now 0xf6e17b2a54364b18007d3bba082a4a68ddc04ad30d64cd6cab24b0b7c25f91a1, previously 0x47a99410fa4b2414e1a50198ecd6f7ba191e3089942f29a3144bd0f37d48af53.
2022-08-25 15:32:30 ✨ Imported #3 (0xf6e1…91a1)
2022-08-25 15:32:31 💤 Idle (0 peers), best: #3 (0xf6e1…91a1), finalized #0 (0xa524…c2b5), ⬇ 0 ⬆ 0
2022-08-25 15:32:36 🙌 Starting consensus session on top of parent 0xf6e17b2a54364b18007d3bba082a4a68ddc04ad30d64cd6cab24b0b7c25f91a1
2022-08-25 15:32:36 🎁 Prepared block for proposing at 4 [hash: 0x41065d03a825b9ab3a11281d5521c4e8d623804b28fab3931fc55af081d488bf; parent_hash: 0xf6e1…91a1; extrinsics (1): [0x5cfc…5083]]
2022-08-25 15:32:36 🔖 Pre-sealed block for proposal at 4. Hash now 0xfd60895534f8ac72e73aa387b87264455ae06e6e484a7a3f50e4b1700798b2f2, previously 0x41065d03a825b9ab3a11281d5521c4e8d623804b28fab3931fc55af081d488bf.
2022-08-25 15:32:36 ✨ Imported #4 (0xfd60…b2f2)
2022-08-25 15:32:36 💤 Idle (0 peers), best: #4 (0xfd60…b2f2), finalized #1 (0x9a76…c3e9), ⬇ 0 ⬆ 0
2022-08-25 15:32:41 💤 Idle (0 peers), best: #4 (0xfd60…b2f2), finalized #2 (0x6027…c86e), ⬇ 14 B/s ⬆ 0

With the --simple-governance flag, you could perform a runtime upgrade test though sudo or council locally.

It's a really useful testing tool.

Fork-Off

This is very similar to the export command. But this command can build a fork-off chain even offline.

The result will be store at <a>.fork-off.

Sometimes, you have already running a node yourself. So, you don't want to fetch the state from a live chain, which is slow. Then you could use this command.

Examples

For convenience, I use the Darwinia Network to demonstrate.

Here is a most common way to use this command. To build a fork-off chain:

darwinia build-spec --raw > darwinia-dev.json
# Export the state from your node.
darwinia export-state -d <PATH TO DATA> --chain <CHAIN> <BLOCK NUMBER> > darwinia-node-export.json
subalfred state fork-off darwinia-node-export.json --renew-consensus-with darwinia-dev.json --simple-governance --disable-default-bootnodes

To run the fork-off chain:

darwinia --chain darwinia-node-export.json.fork-off --alice --tmp

But there is an issue that we build the fork-off chain in this way. The block can not be finalized. After some searching I found some well-known keys were dumped. There some GRANDPA round state old data. Check this question. I'll fix this once I get the well-known keys.

Override

Override state a with b.

In fact, it accepts two chain spec files. So, make sure JSON file contains the object["genesis"]["raw"]["top] field.

The result will be store at <a>.override.

Examples

subalfred state override a.json b.json
# You could check this command's output. It should be empty.
subalfred state diff a.json.override b.json

The Storage Key Command

Calculate the storage key for the storage prefix/item quickly.

Examples

subalfred storage-key --prefix System --item Number
0x26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac

Actually, it equals to twox128(prefix) + twox128(item).

subalfred convert ascii2hex System
subalfred hash --hasher twox128 0x53797374656d
subalfred convert ascii2hex Number
subalfred hash --hasher twox128 0x4e756d626572
0x53797374656d
0x26aa394eea5630e07c48ae0c9558cef7
0x4e756d626572
0x02a5c1b19ab7a04f536c519aca4983ac

0x26aa394eea5630e07c48ae0c9558cef7
+
0x02a5c1b19ab7a04f536c519aca4983ac
=
0x26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac

The Workspace Command

This is a release helper.

Currently, there is only one command.

Update

Update the workspace members version to the given one. If --manifest-path is missing, it will read the current folder's Cargo.toml as the root manifest.

Examples

subalfred workspace update v0.9.1