Run a node

Install, configure and start an SCL node, then confirm it is in sync with the rest of the network. You do not need a local Bitcoin node.

Updated 08 Nov 20263 min read

#Install

  • Install Rust and Cargo.
  • Clone scl-node (opens in a new tab) and build the release binary with cargo build --release. The binary lands at target/release/scl-node.
  • Keep it alongside a writable data directory for state and logs.

You do not need a local Bitcoin node: chain data is read from an Esplora (opens in a new tab) endpoint over HTTP.

#Configure

Configuration comes from a config.toml next to the binary, from environment variables, or both; environment variables override the file. All fields have working defaults.

Example config.toml:

toml
node_id = "my-node"
rest_address = "0.0.0.0:8080"        # client-facing REST API
bind_address = "0.0.0.0:50051"       # gRPC: peer sync and gossip
url = "http://my-node.example:50051" # public gRPC URL advertised to peers
peers = ["http://node1.example:50051", "http://node2.example:50051"]
esplora = "https://blockstream.info/api"
db_path = "./data/scl-node"
data_dir = "./data"
peer_limit = 10

# Optional: stable Ed25519 identity for signing gossip (64 hex chars).
# Omit for an ephemeral identity.
gossip_private_key = ""

# Optional: bearer token protecting private endpoints
# (confirmed-call log, admin operations). Omit to leave them locked.
api_token = ""

The equivalent environment variables:

VariableDefaultPurpose
SCL_NODE_IDscl-node-1Node identifier
SCL_REST_ADDRESS0.0.0.0:8080REST API bind
SCL_BIND_ADDRESS0.0.0.0:50051gRPC bind
SCL_PUBLIC_URLhttp://localhost:50051Public gRPC URL advertised to peers
SCL_PEERSemptyComma-separated peer gRPC URLs
SCL_PEER_LIMIT10Max peers for gossip forwarding
SCL_ESPLORA_URLhttps://blockstream.info/apiEsplora API base (set a testnet URL for testnet)
SCL_DB_PATHdata/scl-nodeDatabase path
SCL_GOSSIP_PRIVATE_KEYemptyEd25519 seed for a stable gossip identity
SCL_API_TOKENemptyBearer token for private endpoints
RUST_LOGinfoLog filter

#Start

bash
./scl-node

There are no subcommands; configuration fully determines behavior. A docker-compose.yml in the repository runs a single node with persistent data if you prefer containers.

On startup your node:

  • Initializes local storage.
  • Fetches the current Bitcoin height from Esplora and anchors its block journal.
  • Reloads the contract registry.
  • Syncs with peers using Merkle-based diffing.
  • Then serves requests, gossips payloads, and watches Bitcoin for new blocks (checking every 60 seconds, with a full peer sync every 5 minutes).

Health check:

bash
curl -i http://localhost:8080/health
# Expect: HTTP/1.1 200 OK

curl http://localhost:8080/node_status

#Verify you're in sync

Compare state roots with another node; matching roots at the same height prove matching state:

bash
curl http://localhost:8080/v2/state_root

For the full REST and gRPC surface, see the Node API reference. Treat the REST surface as current implementation, not a stable public API.

#Validator seats

Anyone can run a node and replay the network. Validator seats on the canonical ledger, which co-sign state roots and earn from the emission pool, are accredited: they are admitted by governance and carry obligations to replay, publish state roots and operate network infrastructure. See Validators and the canonical ledger and XRB and network economics.

Was this page helpful?