Shell Chain Quickstart Guide
Get a local Shell Chain node running in 5 minutes.
See also: Testnet Operator Guide · JSON-RPC API Reference · Post-Quantum Cryptography Guide · Smart Contract Guide · Native Account Abstraction Guide
Prerequisites
- Rust 1.75+ from the official Rust installer page: https://www.rust-lang.org/tools/install
- Git
- curl and python3 for the verification commands
1. Clone and build
git clone https://github.com/ShellDAO/shell-chain.git
cd shell-chain
cargo build --release -p shell-cli --bin shell-node
The binary is at target/release/shell-node.
For convenience, add it to your PATH:
export PATH="$PWD/target/release:$PATH"
2. Generate a key
Shell Chain uses ML-DSA-65 as its primary post-quantum signature scheme (see PQ Crypto Guide). Generate a validator keypair:
printf 'dev-password\n' > .quickstart-password
shell-node --password-file .quickstart-password key generate \
--algorithm mldsa65 \
--output my-key.json
chmod 600 my-key.json
For an interactive run, omit --password-file and enter the password at the prompt. Keep the password and keystore; both are required to start the node.
View the derived address:
shell-node key inspect my-key.json
Note the displayed address (a 0x + 64 lowercase hex string). You'll use it in the genesis file.
3. Initialize genesis
Set a shell variable to the inspected address and create a genesis.json with that address as the sole validator and pre-funded account:
ADDR=$(shell-node key inspect my-key.json | awk '/Address:/ {print $2}')
cat > genesis.json <<EOF
{
"chain_id": 1337,
"chain_name": "shell-local",
"network_type": "Dev",
"timestamp": $(date +%s),
"gas_limit": 30000000,
"extra_data": "shell-genesis",
"consensus": {
"engine": "poa",
"authorities": [
"$ADDR"
],
"block_time_secs": 2,
"epoch_length": 0
},
"alloc": {
"$ADDR": {
"balance": "0x3635c9adc5dea00000"
}
},
"boot_nodes": []
}
EOF
The same file with placeholders looks like this:
{
"chain_id": 1337,
"chain_name": "shell-local",
"network_type": "Dev",
"timestamp": 1735689600,
"gas_limit": 30000000,
"extra_data": "shell-genesis",
"consensus": {
"engine": "poa",
"authorities": [
"0x<YOUR_ADDRESS_64_HEX>"
],
"block_time_secs": 2,
"epoch_length": 0
},
"alloc": {
"0x<YOUR_ADDRESS_64_HEX>": {
"balance": "0x3635c9adc5dea00000"
}
},
"boot_nodes": []
}
Replace 0x<YOUR_ADDRESS_64_HEX> with the address from Step 2. The balance 0x3635c9adc5dea00000 is 1,000 SHELL in wei. Set timestamp to the current Unix epoch (date +%s) or any recent value.
Initialize the data directory:
shell-node --datadir shell-data init --genesis genesis.json --chain-id 1337 --network dev
4. Start a single node
shell-node run \
--datadir shell-data \
--keystore my-key.json \
--password-file .quickstart-password \
--rpc-addr 127.0.0.1:8545 \
--block-time 2000 \
--max-idle-interval 0 \
--network dev \
--rpc-api eth,net,web3,shell
Enter your keystore password when prompted. You should see log output showing blocks being produced every 2 seconds. --max-idle-interval 0 keeps empty-block production enabled for the tutorial; omit it in normal development if you prefer the default idle-skip behavior.
Storage backend: The
--network devflag automatically selects the in-memory backend (no disk writes). For persistent local development, omit--networkand add--db rocksdb.
5. Check block height
Open a new terminal and query the node:
curl -s http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
Expected response:
{"jsonrpc":"2.0","id":1,"result":"0x5"}
The block number should increase every 2 seconds.
6. Check your balance
Using the CLI:
shell-node account balance "$ADDR" --rpc-url http://127.0.0.1:8545
Or via curl:
curl -s http://localhost:8545 \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBalance\",\"params\":[\"$ADDR\",\"latest\"],\"id\":1}"
Expected result: "0x3635c9adc5dea00000" (1,000 Ether).
7. Send a test transaction
Generate a second key to use as the recipient:
shell-node --password-file .quickstart-password key generate \
--algorithm mldsa65 \
--output recipient-key.json
chmod 600 recipient-key.json
RECIPIENT=$(shell-node key inspect recipient-key.json | awk '/Address:/ {print $2}')
Send 1 Ether (1000000000000000000 wei) from your funded account:
shell-node tx send \
--to "$RECIPIENT" \
--value 1000000000000000000 \
--keystore my-key.json \
--password-file .quickstart-password \
--rpc-url http://127.0.0.1:8545
Enter your keystore password when prompted. The command outputs the transaction hash.
Verify the recipient received the funds:
shell-node account balance "$RECIPIENT" --rpc-url http://127.0.0.1:8545
8. Explore the API
Query node information:
curl -s http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"shell_getNodeInfo","params":[],"id":1}' | python3 -m json.tool
List validators:
curl -s http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"shell_getValidators","params":[],"id":1}'
Check client version:
curl -s http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}'
Public Testnet
Live public testnet: RPC
https://testnet-rpc.shell.org· WSSwss://testnet-rpc.shell.org/ws· Explorerhttps://explorer.shell.org· Faucethttps://faucet.shell.org· Chain ID10
See the Testnet Operator Guide for running your own validator node.
Next Steps
- Run a multi-node testnet: See the Testnet Operator Guide for systemd-based validator setup with monitoring.
- Deploy smart contracts: See Smart Contract Guide for deploying Solidity/Vyper contracts with Hardhat or Foundry.
- Full API reference: See JSON-RPC API Reference for all RPC methods.
- Understand the cryptography: See PQ Crypto Guide for details on ML-DSA-65, key formats, and quantum resistance.
- Deploy a contract: Use
shell-node tx deploy --code 0x... --keystore my-key.json. - Make a read-only call: Use
shell-node tx call --to 0x<CONTRACT_ADDRESS_64_HEX> --data 0x....
Last updated: 2026-06-17