Deploying
What deploying a parachain involves.
Deploying to Vitreus testnet is a four-step shape: a chain spec, a runtime hand-off, a collator, and a relay registration that lets the chain produce blocks. The ChainForge walkthrough that ties all four together hasn't shipped yet — when it does, this guide grows to describe it. For now, the conceptual sections below cover what each step is, and the §5 walkthrough pairs every step with the manual path you can drive today via polkadot.js apps and the upstream substrate-node-template.
Sections 1–4 introduce the concepts at the level Maya needs. Sections 5–7 are for Dan: the procedural detail, manual commands, error lookups.
1. What deploying a parachain involves
You have a scaffold that compiles. That's table stakes — it means the runtime code is well-formed, but it doesn't yet mean a chain is producing blocks. To get there, four things have to happen:
- A chain spec describes what your chain looks like at block zero — who has tokens, what it's called, what network it joins.
- The runtime — your Rust code — compiles to a WASM blob the relay chain can store and execute.
- A collator (a node running your chain's runtime) registers on the Vitreus relay chain and starts building blocks.
- The relay validates and finalises those blocks; your chain is live.
Sections 2–4 cover the concepts. Section 5 lays out the current-state walkthrough — what you actually run, today, to get from cargo-check-passes to a block on testnet.
2. Chain spec — what chain_spec.rs in your project does
Every scaffold ships a chain_spec.rs file at the project root. A chain spec is the configuration your chain starts with — who has tokens at block zero, what the chain calls itself, what network it joins. Genesis is the formal name for that “block zero” state; the chain spec is the file that produces it.
The shipped file is a development chain spec: single-node, Alice as sudo, a seeded balance so you can sign transactions immediately. The shape is real — the same ChainSpec::builder() API you'd use for a production deploy. The genesis patch in the shipped file seeds Alice's native balance; for marketplace projects it deliberately leaves the asset registry empty (you create assets post-launch via pallet_assets::create).
chain_spec.rs in your scaffold is a working development chain spec — edit the values directly to tune for your deploy. The raw form (what the relay actually consumes) comes from substrate build-spec --raw against a clone of substrate-node-template pointed at your runtime.3. Runtime hand-off — the WASM blob
The relay chain doesn't run your Rust code. It runs the WASM that your Rust code compiles to. WASM is WebAssembly — a portable, sandboxed bytecode format. Your runtime — the code in runtime/src/lib.rs — compiles to a WASM blob the relay chain stores and executes.
One consequence of this shape worth knowing: Substrate runtimes are upgradable by replacing the WASM blob in storage. A runtime upgrade is a transaction, not a redeploy. You can ship new logic to a live chain by submitting an extrinsic that swaps the blob; the next block runs the new code. (Storage layouts have to migrate forward — that's the spec_version bump and the OnRuntimeUpgrade impl from building §6.)
cargo build --release. The CLI specifics live in reference §5.4. Relay chain and validators — what carries you
You've already met the term parachain on the FAQ: a chain that lives inside a larger network. ChainForge projects target the Vitreus relay, the larger network in that pairing. The relay handles the heavy-duty pieces — security, finality, validator economics — so your chain doesn't have to.
Two node roles you'll see referenced here and in reference material:
- A validator is a node running the relay chain itself. Validators secure the relay; they don't run your chain.
- A collator is the node software that runs your chain and submits its blocks to the relay. You provide collators; the Vitreus Foundation provides validators.
The mechanics of parachain slot leases, slot auctions, and slot mechanics on Vitreus — what determines whether your chain gets a continuously-included slot or has to share a throughput-limited one — are Foundation-coordinated. When the Foundation publishes the slot economics for Vitreus testnet, this section will name the specifics. Today the testnet path is open to projects in development; the mainnet path is a real-money decision and well outside this guide's scope.
5. The deploy steps, in current-state form
This section is the procedural walkthrough. If you're reading along as a non-developer, the gist is: each step below pairs the future automation with the manual command you'd run today. The conceptual setup is in §§1–4 above.
Five steps from compiled-scaffold to block-on-testnet. Each step names what the future automation will do, then the current-state command you run today.
5.1 — Build the runtime WASM
Today: from the workspace root, cargo build -p chainforge-<template>-runtime --release --target wasm32-unknown-unknown. The build pulls down the polkadot-sdk crates on first run (a few minutes) and produces a .wasm file in target/wasm32-unknown-unknown/release/. That blob is what the relay will store.
5.2 — Generate a raw chain spec
Today: substrate build-spec --raw against a clone of substrate-node-template that's been pointed at your runtime crate. The output is the JSON file the relay registration will reference.
chain_spec.rs into the raw form directly, with the dev / testnet / mainnet variants pre-configured) isn't shipped. The substrate build-spec CLI is the working substitute.5.3 — Stand up a collator
Today: clone paritytech/substrate-node-template and point its runtime dependency at your project's runtime crate (a path-or-git dep in node/Cargo.toml). Build: cargo build --release. Launch: ./target/release/node-template --chain chain-spec.raw.json --base-path /tmp/<name>. Adding --validator --alice puts it in dev-validator mode for single-node testing before you register on the relay.
5.4 — Register on the Vitreus testnet relay
Today: open polkadot.js apps — the official browser UI for talking to any Substrate chain. Point it at the Vitreus testnet RPC endpoint, sign in with a wallet account that holds test tokens (see §6), and submit a parasRegistrar.register signed extrinsic — an extrinsic carrying a signature from the account that pays for it. The extrinsic takes your para id, your genesis head, and your WASM blob; submit and watch for inclusion.
5.5 — Confirm blocks
Today: point polkadot.js apps at your collator's RPC endpoint and open the Explorer view. Blocks should be appearing every few seconds. The blockchain pane on the left shows the latest block; the events pane on the right shows what happened in each.
6. Getting test tokens (and why)
This subsection is the one piece of the deploy path without a current-state alternative. Reading it here means you've hit the pending item, not that you've missed an instruction.
Every extrinsic costs gas. Step 5.4 — the registration — is signed by an account that has to pay for it. On testnet, that gas comes from a faucet: a service that hands out test tokens for free.
7. When a step fails
This section is for the developer hitting an error in §5. Errors at the manual-path CLI level fall into the same classes as in-app errors; the lookup table below points into the reference guide's footguns section for the deep dives.
The manual-path steps in §5 each fail with their own error surface: cargo build errors at the CLI, polkadot.js apps surfaces dispatch errors in its UI when an extrinsic fails to apply.
| When | Where it surfaces | Where to look |
|---|---|---|
| Building the runtime WASM | cargo build output | reference §3 (compile-time footguns) |
| Generating the raw chain spec | substrate CLI stderr | substrate-node-template README; usually a runtime-dep path mismatch |
| Standing up the collator | node-template stderr | substrate-node-template README; usually a chain-spec mismatch with the runtime |
| Registering on the relay | polkadot.js apps event pane (dispatch error) | Read the error name in the event; cross-reference reference §3 for known patterns |
| Blocks not appearing | polkadot.js apps Explorer | Collator logs first; check the collator can reach the relay RPC and that your para id matches the chain spec |