Self-Host a Node
You can host a node without using the ZenChain Station app. This guide will walk you through the steps to set up a node and become a validator. It requires technical expertise and is recommended for advanced users. If you choose to self-host, it’s assumed you’re familiar with Docker, shell commands, and general blockchain concepts.
We recommend hosting the node in a cloud environment to ensure it runs 24/7 with minimal to no downtime. If your node goes offline unexpectedly, your stake could be slashed. Setting up a cloud environment is beyond the scope of this guide.
Run a node
We provide instructions on running a node using a Docker image, a pre-written Dockerfile, or without Docker. Although running the node on "bare metal" can give slight performance benefits, we recommend using the published Docker image as it’s the easiest option.
Docker Image
To help you get started quickly, we provide a Docker image of the latest release hosted on GitHub Container Registry (GHCR). The recommended production setup will be explained later.
You can pull the image directly with this command:
docker pull ghcr.io/zenchain-protocol/zenchain-testnet:latest
And run it from the command line.
# development
docker run \
-d \
--name zenchain \
-p 9944:9944 \
-v ./chain-data:/chain-data \
ghcr.io/zenchain-protocol/zenchain-testnet:latest \
./usr/bin/zenchain-node \
--dev
# production
docker run \
-d \
--name zenchain \
-p 9944:9944 \
-v ./chain-data:/chain-data \
ghcr.io/zenchain-protocol/zenchain-testnet:latest \
./usr/bin/zenchain-node \
--base-path=/chain-data \
--rpc-cors=all \
--validator \
--name=ILoveZenchain \
--bootnodes=/dns4/node-7242611732906999808-0.p2p.onfinality.io/tcp/26266/p2p/12D3KooWLAH3GejHmmchsvJpwDYkvacrBeAQbJrip5oZSymx5yrE \
--chain=zenchain_testnet
Alternatively, you can include this setup in a Docker Compose file.
# development
services:
zenchain:
image: ghcr.io/zenchain-protocol/zenchain-testnet:latest
platform: linux/amd64
container_name: zenchain
ports:
- "9944:9944"
command:
- "./usr/bin/zenchain-node"
- "--dev"
# production
services:
zenchain:
image: ghcr.io/zenchain-protocol/zenchain-testnet:latest
platform: linux/amd64
container_name: zenchain
ports:
- "9944:9944"
volumes:
- ./chain-data:/chain-data
command:
- "./usr/bin/zenchain-node"
- "--base-path=/chain-data"
- "--rpc-cors=all"
- "--validator"
- "--name=ILoveZenchain"
- "--bootnodes=/dns4/node-7242611732906999808-0.p2p.onfinality.io/tcp/26266/p2p/12D3KooWLAH3GejHmmchsvJpwDYkvacrBeAQbJrip5oZSymx5yrE"
- "--chain=zenchain_testnet"
Fresh Build With Docker
We provide a Dockerfile within the Zenchain node's GitHub repository that can be used to build a development image. We'll walk you through the steps.
Clone the Repo
First, clone the node repository from GitHub and navigate to the root directory.
git clone https://github.com/zenchain-protocol/zenchain-node.git
cd ./zenchain-node
Production or Development?
The main difference between the development image and the production image is the command used to build the node. If you will run the node as a Zenchain validator, you can modify the Dockerfile
for a production build. Locate the build command cargo build --release
and change it to use the "production" build profile.
# development
cargo build --release
# production
cargo build --profile=production
Build and Run
To build and run the image, run the following commands from the root of the repo. The image may take over 20 minutes to build initially. By default, the node uses port 9944.
docker build -t zenchain-node .
# development
docker run -t zenchain-node --dev
# production
docker run -t zenchain-node \
--base-path=/chain-data \
--rpc-cors=all \
--validator \
--name="Your node name" \
--bootnodes=/dns4/node-7242611732906999808-0.p2p.onfinality.io/tcp/26266/p2p/12D3KooWLAH3GejHmmchsvJpwDYkvacrBeAQbJrip5oZSymx5yrE \
--chain=zenchain_testnet
Fresh Build Without Docker
To run the node without Docker, you’ll need to have the Rust toolchain installed. If it’s not already installed, follow the instructions on the Rust programming language website.
For Linux, MacOS, and Windows, you may need extra dependencies.
Additional Dependencies for Linux
Execute the following command (Ubuntu as reference):
sudo apt install -y clang libssl-dev llvm libudev-dev pkg-config protobuf-compiler make
Additional Dependencies for MacOS
If you have an Apple M1 ARM system, you must install Apple Rosetta 2
:
softwareupdate --install-rosetta
Execute the following command to install additional deps:
brew install openssl
brew install protobuf
Additional Dependencies for Windows
LLVM: Download and execute the installer "https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.2/LLVM-18.1.2-win64.exe"
Download the Protocol Buffers package: "https://github.com/protocolbuffers/protobuf/releases/download/v26.1/protoc-26.1-win64.zip"
Once downloaded, extracts all files in a choosen path; then create the PROTOC
environment variable that points to the protocol buffer executable, for example:
setx PROTOC C:\protoc\bin\protoc.exe /m
then restart the shell.
Clone the Repo
Once your environment is set up, you are ready to clone the node repository from GitHub and navigate to the repository root directory.
git clone https://github.com/zenchain-protocol/zenchain-node.git
cd ./zenchain-node
Build the Node
The Zenchain node and runtime are written in Rust, so we will use the Cargo CLI tool to build the node. If you will use the node as a validator, make sure to build it with the "production" build profile instead of "release".
# development
cargo build --release
# production
cargo build --profile=production
The node can take more than 20 minutes to build for the first time. Subsequent builds are significantly faster due to caching. The "release" build profile compiles faster by skipping performance optimizations.
Run the Node
You can now run the node with the executable you built in the previous step. The node uses port 9944 by default. The recommended production configuration will be explained shortly.
# development
./target/production/zenchain-node --dev
# production
./target/production/zenchain-node \
--base-path=/chain-data \
--rpc-cors=all \
--validator \
--name="Your node name" \
--bootnodes=/dns4/node-7242611732906999808-0.p2p.onfinality.io/tcp/26266/p2p/12D3KooWLAH3GejHmmchsvJpwDYkvacrBeAQbJrip5oZSymx5yrE \
--chain=zenchain_testnet
Configuration
We recommend initially running a validator node with the following command line arguments. The table explains the purpose of each option. We will soon change this configuration to prevent unsafe RPC calls, but for now it is important to use the --unsafe-rpc-external
argument so you can update the node's "session keys" and connect the node to your Ethereum account.
--base-path=/chain-data
--rpc-cors=all
--unsafe-rpc-external
--validator
--name="Your node name"
--bootnodes=/dns4/node-7242611732906999808-0.p2p.onfinality.io/tcp/26266/p2p/12D3KooWLAH3GejHmmchsvJpwDYkvacrBeAQbJrip5oZSymx5yrE
--chain=zenchain_testnet
Option | Explanation |
---|---|
--base-path=/chain-data | Where your node's database will be stored |
--rpc-cors=all | Enable CORS to allow RPC requests that originate in a browser environment |
--unsafe-rpc-external | Enable all RPC methods, including unsafe methods |
--validator | Run as a validator node |
--name | Any name you want! |
--bootnodes=... | Node's initial bridge to the network. Do not change this! |
--chain=zenchain_testnet | Tells the node to know which chain specification to use. Do not change this! |
Session Keys
Your node is identified in Zenchain's consensus protocol by Session Keys, which are comprised of accounts for three consensus mechanisms: RAGE, GUARDIAN, and "I'm Online". RAGE is responsible for block production, GUARDIAN is responsible for block finality, and "I'm Online" tells the network that your node is online during the active session.
Generate Session Keys
To generate Session Keys for your node, you need to complete an RPC call author_rotateKeys
using your node's RPC endpoint. The RPC method will generate new Session Keys, insert them into your node's secure keyring, and return the full set of public keys in serialized form as a hex string. You will need the output of the RPC call for the next step.
Zenchain nodes support the JSON-RPC 2.0 standard format.
Set Keys for your Ethereum Account
Using the output from the author_rotateKeys
RPC call, submit a transaction calling the setKeys
function of the KeyManager
precompile. The transaction will associate the Session Keys with your Ethereum account.
Key Manager Precompile
Contract | Ethereum Address | Solidity Interface |
---|---|---|
KeyManager | 0x0000000000000000000000000000000000000802 | GitHub |
Using the polkadotjs-apps Tool
Zenchain is compatible with some tools in the Substrate ecosystem. You can use the polkadotjs-apps tool, originally created for the Polkadot blockchain, for a simple session key generation UX. Refer to the polkadotjs-apps documentation here for more information: https://wiki.polkadot.network/docs/maintain-guides-how-to-validate-polkadot#generating-the-session-keys.
You can use the polkadotjs-apps tool with an injected Ethereum wallet, such as MetaMask. To ensure the app works correctly with your wallet, you'll need to make sure an app setting is configured correctly. Go to the app's "Settings" in the top toolbar. From the "General" tab, make sure the "in-browser account creation" option is set to "Allow local in-browser account storage". Your wallet should now work as expected.
Update Node Configuration and Restart
Now that you've set your session keys with the rotateKeys
RPC method and the setKeys
transaction, you can restart your node with an updated configuration to prevent unsafe RPC calls. You can also remove CORS support from the configuration since RPC will be disabled.
--base-path=/chain-data
--validator
--name="Your node name"
--bootnodes=/dns4/node-7242611732906999808-0.p2p.onfinality.io/tcp/26266/p2p/12D3KooWLAH3GejHmmchsvJpwDYkvacrBeAQbJrip5oZSymx5yrE
--chain=zenchain_testnet
Unlike an archive node, which may be used as a secure RPC endpoint, it is not possible to run a validator node with the --rpc-external
and --rpc-methods=Safe
options. If you do not enable RPC requests, you will not be able to submit transactions or make other RPC requests to the node. However, validator nodes are not typically used as RPC endpoints. Keeping the --unsafe-rpc-external
option enabled is insecure. We highly recommend restarting your validator node with the --unsafe-rpc-external
flag removed from your configuration.
Stake ZCX and Request to Validate
Once you've set your Session Keys, you're ready to submit a request to validate.
You can use the Zenchain Station to stake ZCX and change your staker status to "Validator".
Alternatively, you can stake ZCX via transactions and call the validate()
function in the NativeStaking
precompile contract.
Please refer to our staking guide, How to Stake, for step-by-step instructions.
To be a validator, you must have a minimum amount of ZCX staked. Learn more about staking, validating, and the minimum amount of staked ZCX required for validators.