Skip to main content

Demo Mode

MiniLedger includes a built-in demo command that creates a fully functional 3-node Raft cluster on your local machine with a single command. The demo deploys a sample token smart contract, executes example transactions, and opens the block explorer dashboard so you can see everything in action.

This is the fastest way to evaluate MiniLedger's multi-node consensus, smart contracts, and query capabilities without any manual setup.

Run the Demo

npx miniledger demo

That is it. One command, no configuration.

If you installed MiniLedger globally:

miniledger demo

What the Demo Does

The demo command automates the following sequence:

1. Initializes Three Nodes

Three separate MiniLedger nodes are created, each with its own data directory, Ed25519 identity, and configuration:

NodeData DirectoryP2P PortAPI PortRole
node-1./demo-data/node-144404441Leader (initially)
node-2./demo-data/node-244504451Follower
node-3./demo-data/node-344604461Follower

2. Forms a Raft Cluster

The three nodes discover each other via WebSocket P2P connections and perform Raft leader election. One node becomes the leader and begins producing blocks, while the other two replicate the chain as followers.

You will see log output similar to:

[demo] Starting node-1 (P2P: 4440, API: 4441)
[demo] Starting node-2 (P2P: 4450, API: 4451)
[demo] Starting node-3 (P2P: 4460, API: 4461)
[demo] Raft cluster formed. Leader: node-1
[demo] All 3 nodes connected and synced

3. Deploys a Token Smart Contract

A sample SimpleToken smart contract is deployed to the cluster. This contract implements basic token functionality:

  • mint -- Create new tokens and assign them to an account
  • transfer -- Move tokens from one account to another
  • balanceOf -- Query the token balance of an account

The contract is written in plain JavaScript:

// SimpleToken contract (deployed automatically by demo)
module.exports = {
mint({ to, amount }, state) {
const balance = state.get(`balance:${to}`) || 0;
state.set(`balance:${to}`, balance + amount);
return { to, newBalance: balance + amount };
},

transfer({ from, to, amount }, state) {
const fromBalance = state.get(`balance:${from}`) || 0;
if (fromBalance < amount) throw new Error('Insufficient balance');
const toBalance = state.get(`balance:${to}`) || 0;
state.set(`balance:${from}`, fromBalance - amount);
state.set(`balance:${to}`, toBalance + amount);
return { from, to, amount };
},

balanceOf({ account }, state) {
return { account, balance: state.get(`balance:${account}`) || 0 };
},
};

4. Executes Sample Transactions

The demo submits a series of transactions to populate the ledger with realistic data:

[demo] Deploying SimpleToken contract...
[demo] Minting 1000 tokens to alice
[demo] Minting 500 tokens to bob
[demo] Transferring 200 tokens from alice to bob
[demo] Transferring 50 tokens from bob to charlie
[demo] All sample transactions committed

After the transactions complete, the token balances are:

AccountBalance
alice800
bob650
charlie50

5. Opens the Block Explorer

The demo automatically opens the block explorer dashboard in your default browser at:

http://localhost:4441

From the dashboard, you can:

  • Browse all produced blocks and inspect their contents
  • View each transaction, including the smart contract invocations
  • Query the world state to see token balances
  • Monitor the Raft cluster health across all three nodes

Interacting with the Demo Cluster

While the demo is running, you can interact with any of the three nodes using curl or the CLI.

Query Token Balances

# Query via the leader node (port 4441)
curl "http://localhost:4441/api/query?sql=SELECT * FROM state WHERE key LIKE 'balance:%'"

Response:

{
"results": [
{ "key": "balance:alice", "value": "800" },
{ "key": "balance:bob", "value": "650" },
{ "key": "balance:charlie", "value": "50" }
]
}

Submit Additional Transactions

You can submit your own transactions to the running cluster:

# Transfer tokens from alice to a new account
curl -X POST http://localhost:4441/api/tx \
-H "Content-Type: application/json" \
-d '{
"type": "contract",
"contract": "SimpleToken",
"function": "transfer",
"args": { "from": "alice", "to": "dave", "amount": 100 }
}'

Check Cluster Status

Query each node to verify they are in sync:

# Node 1 (leader)
curl http://localhost:4441/api/status

# Node 2 (follower)
curl http://localhost:4451/api/status

# Node 3 (follower)
curl http://localhost:4461/api/status

All three nodes should report the same block height.

List Connected Peers

miniledger peers list --api-port 4441

Output:

Connected Peers (2)
node-2 ws://127.0.0.1:4450 follower synced
node-3 ws://127.0.0.1:4460 follower synced

Testing Fault Tolerance

The demo cluster is a great way to observe Raft fault tolerance in action.

Simulate a Node Failure

In a separate terminal, find and stop one of the follower nodes:

# The demo logs the PID of each node. You can also use:
curl -X POST http://localhost:4451/api/admin/shutdown

After stopping node-2, the cluster continues to operate with two of three nodes (which satisfies the Raft quorum requirement). Transactions submitted to the leader are still committed and replicated to the remaining follower.

Observe Leader Election

If you stop the leader node instead, the two remaining followers will hold a new election and one of them will become the new leader. You can observe this in the log output:

[node-3] Raft election timeout. Starting election for term 2.
[node-3] Received vote from node-2. Won election.
[node-3] Became leader for term 2. Resuming block production.

Transactions should now be submitted to the new leader's API port.

Stopping the Demo

Press Ctrl+C in the terminal where the demo is running:

[demo] Shutting down all nodes...
[demo] node-1 stopped
[demo] node-2 stopped
[demo] node-3 stopped
[demo] Demo data saved in ./demo-data

The demo data is preserved in ./demo-data. You can restart the cluster by running miniledger demo again from the same directory, or delete the directory to start fresh:

rm -rf ./demo-data

Demo Command Options

The demo command accepts optional flags for customization:

FlagDefaultDescription
--nodes3Number of nodes to start
--base-p2p-port4440Starting P2P port (increments by 10 per node)
--base-api-port4441Starting API port (increments by 10 per node)
--no-browserfalseDo not open the block explorer automatically
--data-dir./demo-dataBase directory for demo node data

Example with custom options:

miniledger demo --nodes 5 --base-p2p-port 6000 --base-api-port 6001 --no-browser

Next Steps

Now that you have seen MiniLedger running as a multi-node cluster with smart contracts:

  • Configuration -- Understand all the options you can tune for production deployments
  • Multi-Node Clusters -- Set up a real cluster across multiple machines
  • Smart Contracts -- Write your own JavaScript smart contracts
  • Governance -- Learn how to manage network changes through on-chain proposals