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


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 dev flag automatically selects the in-memory backend (no disk writes). For persistent local development, omit --network and 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 · WSS wss://testnet-rpc.shell.org/ws · Explorer https://explorer.shell.org · Faucet https://faucet.shell.org · Chain ID 10

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