Talk to Your Node: Bitcoin Verification via SSH
Audience: Intermediate — has a running StartOS node and basic terminal comfort
Duration: 90 min
Outcomes: By the end, you will:
- Set up SSH key-based access to a StartOS Bitcoin node
- Independently verify Bitcoin's total supply using your own node
- Read mempool conditions and estimate transaction fees from your own data
- Understand SSH security: threat models, key protection, and agent trade-offs
- Query peers, mining difficulty, and network state via bitcoin-cli
Abstract
Your Bitcoin node validates every block and every transaction, but you have probably never asked it a direct question. This tutorial opens a secure SSH tunnel to your StartOS node and walks you through querying it: verifying the total money supply, reading the mempool, estimating fees, inspecting blocks, and monitoring the network. By the end, you will know how to get answers from your own copy of the blockchain instead of trusting a website.
The tutorial uses an AI agent (like Claude Code) as the primary interface for running commands, but every command is a standard bitcoin-cli call you can type yourself. Appendix A covers the full command reference so you can go direct whenever you want.
Concept Primer
What is SSH?
SSH (Secure Shell) is a way to remotely control a computer using text commands. Instead of sitting in front of your node, you type commands from your laptop and they execute on the node as if you were there. The connection is encrypted end-to-end, so nobody on your network can see what you are doing.
How Key Pairs Work
SSH uses a key pair for authentication: a private key on your laptop (like a password file) and a public key on your node (like a lock). When you connect, your computer proves it has the private key without ever sending it. The node checks this proof against the public key you registered. If they match, you are in.
This is more secure than a password:
- The private key never leaves your machine
- There is nothing to guess or brute-force (256 bits of randomness)
- Each key pair is unique to you
Agenda
- Why Talk to Your Node (10 min) — motivation, what SSH is, course overview
- Setup (25 min) — key generation, StartOS registration, first connection, agent config
- Security (10 min) — threat model, key protection, checklist
- Your First Verification (25 min) — supply, mempool, fees, blocks, DIY command
- What Your Node Sees (15 min) — peers, fee dynamics, mining, bandwidth
- Buffer / Exploration (5 min) — try commands from Appendix A
Prerequisites
- StartOS node — Running Bitcoin Core, fully synced
- Laptop or desktop — On the same local network as your node
- Terminal access — Terminal on Mac/Linux, PowerShell or Git Bash on Windows
- AI agent with terminal access — Claude Code or another assistant that can run shell commands on your behalf
No programming experience required. No Linux experience required. If you can type and follow instructions, you can do this.
Section 1: Why Talk to Your Node
You bought a Bitcoin node. You plugged it in, synced the blockchain, and now it sits in your closet humming away. It is validating every transaction and every block — enforcing Bitcoin's rules without asking anyone for permission.
But right now, you are taking its word for it. You have not actually looked.
Bitcoin's entire value proposition rests on one idea: you do not have to trust anyone. Not a bank, not an exchange, not a block explorer website. You can verify everything yourself. But most node runners do not. They plug in the hardware, check the dashboard occasionally, and trust that it is working.
The blockchain data sitting on that device is the most complete, independently verified financial record in existence — and most people never look at it directly. When you check your balance on a block explorer, you are trusting that website to show you accurate data. None of that trust is necessary. Your node has the same data. It verified every byte of it.
What We Are Building Toward
Here is what it looks like when we are done. You open Claude (or any AI assistant with terminal access) and say:
"Check my node's block height and tell me what's in the mempool."
Claude connects to your node over SSH, runs the commands, and comes back with:
"Your node is at block 940,219 — fully synced. The mempool has 45,231 unconfirmed transactions totaling 23.8 MB, with a minimum relay fee of 1 sat/vbyte. Next-block fee estimate is about 12 sats/vbyte."
Or you ask:
"Verify the total bitcoin supply."
And a few minutes later:
"Your node counted every unspent output in the blockchain. Total supply: 20,000,457.41 BTC across 164.9 million UTXOs. This matches the expected issuance schedule — no extra bitcoin have been created."
A note on trust: A course about not trusting third parties asks you to trust an AI to talk to your node. Claude is a tool running on your machine, executing commands you can see and audit. It cannot move your bitcoin or change your node's configuration with the read-only commands used here. Every command Claude runs is a bitcoin-cli command you could type manually. Appendix A covers the full reference.
Section 2: Setup
This section gets you from zero to connected. By the end, you will have an SSH key, your node will recognize it, and you will have typed your first command on a remote machine.
Step 1: Generate an SSH Key
Open a terminal on your computer (Terminal on Mac/Linux, PowerShell or Git Bash on Windows).
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_mynode
-t ed25519— the algorithm. Ed25519 is modern, fast, and secure.-f ~/.ssh/id_ed25519_mynode— where to save the key. Give it a descriptive name.
It will ask you to set a passphrase. Do it. This encrypts the key file so that even if someone copies it off your machine, they cannot use it without the passphrase.
This creates two files:
~/.ssh/id_ed25519_mynode— your private key. Never share this. Never move it off this machine.~/.ssh/id_ed25519_mynode.pub— your public key. This goes on the node. Safe to share.
Windows note: ~ means C:\Users\YourUsername. The .ssh folder should already exist. If not, create it.
Step 2: Add Your Public Key to StartOS
View your public key:
# Mac/Linux
cat ~/.ssh/id_ed25519_mynode.pub
# Windows (PowerShell)
type C:\Users\YourUsername\.ssh\id_ed25519_mynode.pub
- Copy the entire output (it starts with
ssh-ed25519and ends with your username) - Open your StartOS dashboard in a browser
- Go to System > SSH Keys
- Paste the public key and save
That is it. Your node now recognizes your laptop.
Step 3: Find Your Node's Address
You need your node's IP address on your local network. Check one of these:
- StartOS dashboard: the address bar in your browser already has it (something like
192.168.1.50) - Router admin page: look for connected devices — find the one running StartOS
- StartOS hostname: a
.localhostname visible in the dashboard. This works on Mac and Linux but is unreliable on Windows.
Step 4: Connect
ssh -i ~/.ssh/id_ed25519_mynode start9@192.168.1.50
Replace 192.168.1.50 with your node's actual IP.
-ipoints to your private keystart9is the default username on StartOS
First connection: You will see a message asking if you trust the server's fingerprint. Type yes. This only happens once — SSH remembers the server after that.
If everything worked, your terminal prompt changes to something like:
start9@wood-opals:~$
You are on your node. Type exit to disconnect and return to your laptop's terminal.
Step 5: Create a Shortcut
Create or edit ~/.ssh/config on your laptop so you never have to type the full connection string again:
Host mynode
HostName 192.168.1.50
User start9
IdentityFile ~/.ssh/id_ed25519_mynode
IdentitiesOnly yes
Replace the IP with your node's address. Now connecting is just:
ssh mynode
Step 6: Set Up for Your AI Agent
Your AI agent cannot type passphrases interactively, so you need to load your key into an SSH agent first.
Mac/Linux:
ssh-add ~/.ssh/id_ed25519_mynode
Enter your passphrase once. The agent holds the decrypted key in memory until you log out.
Windows (PowerShell as Administrator):
# Check if the agent is running
Get-Service ssh-agent
# If it says "Stopped", start it and set it to auto-start:
Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent
# Add your key (prompts for passphrase once)
C:\Windows\System32\OpenSSH\ssh-add.exe C:\Users\YourUsername\.ssh\id_ed25519_mynode
Git Bash users: Git Bash ships its own SSH binary that does not talk to the Windows agent. Add these aliases to your ~/.bashrc:
export GIT_SSH="/c/Windows/System32/OpenSSH/ssh.exe"
alias ssh='/c/Windows/System32/OpenSSH/ssh.exe'
alias scp='/c/Windows/System32/OpenSSH/scp.exe'
Then reload: source ~/.bashrc
Verify your agent can connect:
ssh mynode "echo connected"
If it prints connected without asking for a passphrase, your AI agent can use it too.
When you are done for the day: Flush the keys from the agent:
# Mac/Linux
ssh-add -D
# Windows
C:\Windows\System32\OpenSSH\ssh-add.exe -D
Section 3: Security
You now have remote access to your Bitcoin node. That is a powerful thing, and it is worth understanding exactly what it means before you start using it.
What You Just Opened
SSH gives you a command-line terminal on your server. On StartOS, the SSH user (start9) has passwordless sudo — meaning there is no second gate between "logged in" and "full control." For this tutorial, we only use read-only commands. But the access itself is broader than what we use it for.
Who Can Reach Your Node?
| Setup | Risk | Who can attempt to connect |
|---|---|---|
| LAN-only (your setup) | Lower | Only devices on your home network |
| Port 22 forwarded on router | High | Anyone on the internet |
| SSH over Tor hidden service | Medium | Anyone who discovers the .onion address |
Never forward port 22 on your router. Automated bots scan the entire internet for open SSH ports around the clock. If you need remote access, use a VPN or Tor — never raw SSH over the open internet.
What Is at Stake
If someone obtained your SSH key and passphrase, they could:
- Stop, start, or reconfigure services (Bitcoin Core, Electrs, etc.)
- Read configuration files containing RPC credentials
- Modify settings or install malware
- Wipe the blockchain data (hundreds of gigabytes to re-download)
- If a hot wallet is loaded: potentially send bitcoin
What they cannot do:
- Steal bitcoin from a hardware wallet connected through this node. The node validates transactions but never holds the hardware wallet's private keys.
- Compromise the Bitcoin network. Your node is one of tens of thousands. It has no special authority.
- Access funds in external wallets that connect via Electrum Server. Those wallets hold their own keys.
Key distinction: Your node is a verification tool, not a custody tool. If you use a hardware wallet, SSH access is a privacy and convenience concern, not a funds-at-risk concern.
The SSH Agent Trade-Off
If you loaded your key into the SSH agent (Step 6), the agent holds your decrypted key in memory. Any process running as your user can silently ask the agent to sign an authentication challenge — meaning malware or a rogue script could SSH to your server without your knowledge. The agent does not prompt you.
This is the same security model used by every developer with GitHub SSH keys. It is standard practice. But you should:
- Flush the agent when you are done working:
ssh-add -D - Do not leave the agent loaded while running untrusted software
- Think of agent time as a session — load the key when you need it, flush it when you are done
Hot Wallet Check
Check if any wallets are loaded on your node:
ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli listwallets"
If wallets are loaded and unencrypted, anyone with SSH access can spend from them. The standard recommendation: use a hardware wallet, and let the node handle validation only.
Security Checklist
Before moving on, confirm:
- You used an Ed25519 key with a strong passphrase
- Your node has key-only authentication (StartOS default — no action needed)
- Port 22 is NOT forwarded on your router
- No hot wallets are loaded on the node (or you understand the risk)
- If using the SSH agent, you know to flush it when done
- You are using a hardware wallet for any real funds
Section 4: Your First Verification
This is the section the setup was for. You are about to independently verify facts about Bitcoin using your own node — no websites, no APIs, no trust required.
Tell your AI agent what you want to know and it will run the commands over SSH. If you want to understand what is happening under the hood, Appendix A covers every command in detail.
Is Your Node Synced?
Before verifying anything, make sure your node is caught up with the network. Ask your agent:
"Check if my node is fully synced."
The agent runs getblockchaininfo and checks that blocks equals headers (all known blocks downloaded and validated) and verificationprogress is at or near 1 (100% verified).
What "synced" actually means: your node downloaded every block ever produced — starting from the genesis block in January 2009 — and independently validated every transaction in every one of them. It checked every signature, verified every input was unspent, confirmed every coinbase reward was correct, and enforced every consensus rule.
Verify the Money Supply
This is the command that makes running a node worth it.
"Verify the total bitcoin supply on my node."
The agent runs gettxoutsetinfo, which scans every unspent transaction output (UTXO) in the entire blockchain. This takes several minutes — it is counting over 160 million individual outputs and summing them.
| Field | Value | Meaning |
|---|---|---|
| Total supply | ~20,000,457 BTC | Every bitcoin that currently exists |
| UTXO count | ~164.9 million | Individual unspent outputs |
| Transactions | ~114.4 million | Total transactions ever processed |
| UTXO set size | ~11.3 GB | How much space the state takes on disk |
The UTXO set hash: The result includes a hash_serialized_3 field — a cryptographic fingerprint of the entire UTXO set. If your hash matches another node's hash at the same block height, you have both independently proven you agree on the exact state of every bitcoin in existence. No coordination needed. No trust required. Just math.
Check the Mempool
The mempool is where unconfirmed transactions wait to be included in a block. Every node maintains its own mempool.
"What's in my node's mempool right now?"
| Field | What it tells you |
|---|---|
| Transaction count | How many transactions are waiting for confirmation |
| Total size | Combined size in bytes — relates to how many blocks it would take to clear |
| Total fees | Sum of all fees waiting to be collected by miners |
| Minimum fee | The lowest fee rate your mempool will accept (rises when the mempool is full) |
Estimate Fees
"What's the fee estimate for next-block confirmation? And for within an hour?"
- Next block (1 block): The fee rate needed to likely get into the very next block. This is the "urgent" rate.
- Within an hour (6 blocks): A more economical rate for transactions that can wait.
- Within a day (144 blocks): The cheapest rate that will still confirm eventually.
The fee rate is expressed in sats/vbyte — satoshis per virtual byte of transaction data. A typical transaction is about 140 vbytes, so multiply the rate by 140 to estimate your total fee in satoshis.
Inspect a Block
"Show me the latest block."
| Field | What it tells you |
|---|---|
| Height | Position in the chain (0 = genesis block) |
| Transaction count | How many transactions the miner included |
| Timestamp | When the miner started working on it |
| Difficulty | Mining difficulty when this block was found |
| Confirmations | How many blocks have been built on top of it |
| Previous block hash | The block before this one — this is what makes it a chain |
The Genesis Block: Block 0, mined by Satoshi Nakamoto on January 3, 2009. It contains the famous coinbase message: "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks." Every block since then links back to this one through an unbroken chain of hashes. Your node verified all of them.
Look Up a Transaction
If you have a transaction ID (txid), your node can decode it:
"Look up this transaction: [paste txid]"
You will see the inputs (where the bitcoin came from), outputs (where it went and how much), fee (how much the sender paid the miner), and which block confirmed it.
Do It Yourself
You have been letting your agent handle the commands. Now try one yourself. Open your terminal and type this exactly:
ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli getblockcount"
That is it. One command. Your laptop connects to your node over SSH, reaches into the Bitcoin Core container, asks for the current block height, and prints the number.
No AI. No website. No intermediary. Your laptop asked your node a question and got a direct answer. The number you see is the block height your node has verified — every block from genesis to that number, independently validated by your hardware.
Section 5: What Your Node Sees
Your node is not just a database of old blocks. It is an active participant in the Bitcoin network — connected to other nodes, relaying transactions, validating new blocks as they arrive, and maintaining its own view of the network's current state.
Your Peers
Your node is connected to a handful of other nodes around the world. A healthy node typically has 8–10 outbound connections and may accept inbound connections too. The total is usually between 8 and 125.
"How many peers is my node connected to? Are any on Tor?"
Things to look for in peer details:
- Tor peers: Connections over Tor show up with
.onionaddresses. StartOS routes through Tor by default. - Inbound vs. outbound: Outbound peers are ones you chose. Inbound peers found you. A mix of both is healthy.
- Version diversity: Your peers may run different versions of Bitcoin Core. As long as they follow consensus rules, this is fine — and good for the network.
- Data exchanged: High byte counts mean active peers.
The Mempool in Motion
Every time someone broadcasts a transaction, it ripples through the network from node to node. Your node receives it from a peer, validates it (checks that the inputs are unspent, the signatures are valid, the fee meets the minimum), and adds it to its mempool. Then it relays the transaction to its other peers.
Your mempool is your node's view of unconfirmed transactions. It is not identical to every other node's mempool — transactions propagate at different speeds, nodes have different minimum fee policies, and mempool size limits vary.
When the Mempool Gets Full
Your node allocates 300 MB by default for the mempool. When it fills up, the node drops the lowest-fee transactions to make room for higher-fee ones. The mempoolminfee field rises — your node is being selective about what it keeps.
"Is the mempool full right now? What's the minimum fee to get in?"
Fee Dynamics
Bitcoin Core looks at the last several hundred blocks and tracks which fee rates got confirmed in how many blocks. From this, it builds a statistical model. This is more sophisticated than most fee estimation websites, which often just look at the current mempool.
"What are the fee estimates for 1 block, 6 blocks, and 144 blocks?"
If the gap between next-block and next-day is large, the network is congested. If they are close together, the network is quiet and patience does not save much.
Mining and Difficulty
Mining difficulty adjusts every 2,016 blocks (roughly two weeks) to keep the average block time at 10 minutes regardless of how much computing power is on the network.
"What's the current mining difficulty? When was the last adjustment?"
Your node estimates the total hash rate by looking at how quickly blocks are being found relative to the difficulty target. As of early 2026, the Bitcoin network computes hundreds of exahashes per second — more computational work per second than any other system in human history.
Bandwidth and Identity
"How much data has my node sent and received since it last started?"
A fully synced node with default settings typically uses 50–200 GB per month. Your node also broadcasts a version string to its peers and shows which networks it is reachable over (IPv4, IPv6, Tor, I2P). StartOS nodes are typically Tor-connected, so peers see your .onion address, not your home IP.
Appendix A: Under the Hood
This appendix covers what your agent does behind the scenes when it queries your node. If you want to run commands manually, understand the container model, or look up a specific command, this is the reference.
The Container Model
StartOS does not run Bitcoin Core directly on the server. It runs inside a Podman container — an isolated environment that packages the software with everything it needs. Think of your server as an apartment building. Each service (Bitcoin Core, Electrum Server, Lightning) lives in its own apartment.
This means you cannot just type bitcoin-cli on the server. You need to reach into the container first:
sudo podman exec bitcoind.embassy bitcoin-cli <command>
To open an interactive shell inside the container:
sudo podman exec -it bitcoind.embassy bash
Now you can type bitcoin-cli commands without the podman exec prefix. Type exit to leave.
Container Management
| Command | What it does |
|---|---|
sudo podman ps | List running containers |
sudo podman logs bitcoind.embassy --tail 50 | Last 50 lines of Bitcoin Core logs |
sudo podman logs bitcoind.embassy --follow | Follow logs in real time (Ctrl+C to stop) |
sudo podman restart bitcoind.embassy | Restart Bitcoin Core (safe) |
Create a Shortcut
Add an alias to your server's .bashrc to skip the podman exec prefix:
ssh mynode
echo 'alias btc="sudo podman exec bitcoind.embassy bitcoin-cli"' >> ~/.bashrc
source ~/.bashrc
Now commands are just:
btc getblockcount
btc getmempoolinfo
btc estimatesmartfee 6
Command Reference
All commands are read-only. You cannot break your node by running these.
Blockchain:
| Command | What it returns |
|---|---|
getblockchaininfo | Chain, height, sync status, pruning, disk size |
getblockcount | Current block height (just the number) |
getbestblockhash | Hash of the latest block |
getblock "hash" | Full details of a specific block |
getblockhash <height> | Block hash by height |
getdifficulty | Current mining difficulty |
getchaintxstats | Transaction rate over time |
UTXO Set:
| Command | What it returns |
|---|---|
gettxoutsetinfo | Total supply, UTXO count, set size (takes minutes) |
gettxout "txid" n | Whether a specific output is unspent |
Mempool:
| Command | What it returns |
|---|---|
getmempoolinfo | Size, tx count, memory usage, min fee |
getrawmempool | List of all unconfirmed transaction IDs |
estimatesmartfee <blocks> | Fee rate for confirmation in N blocks |
Network:
| Command | What it returns |
|---|---|
getnetworkinfo | Version, protocol, connections, networks |
getpeerinfo | Detailed info on every connected peer |
getconnectioncount | Number of peers (just the number) |
getnettotals | Total bytes sent and received |
Mining:
| Command | What it returns |
|---|---|
getmininginfo | Difficulty, hash rate, current block |
getnetworkhashps | Estimated network hash rate |
Reading JSON Output
Most commands return JSON. Here is an example from getblockchaininfo:
{
"chain": "main",
"blocks": 940219,
"headers": 940219,
"bestblockhash": "00000000000000000000ba29...",
"difficulty": 145042165424853.3,
"verificationprogress": 1,
"pruned": false,
"size_on_disk": 826789612252
}
Key things to check: "chain": "main" (you are on mainnet), "blocks" equals "headers" (fully synced), "verificationprogress": 1 (100% verified), "pruned": false (full node).
Appendix B: Tips & Troubleshooting
Quick Status Check
Three commands give you a fast snapshot:
ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli getblockcount"
ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli getconnectioncount"
ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli getmempoolinfo"
Block height, peer count, mempool size. If all three return reasonable numbers, your node is synced, connected, and healthy. Or just ask your agent: "Is my node healthy?"
Common Errors
"Connection refused" when SSHing
ssh: connect to host 192.168.1.50 port 22: Connection refused
Cause: SSH server is not running, or the IP address is wrong.
Fix: Check your node's IP address — IPs can change if you do not have a static lease on your router. Look up the current address in your router's device list or the StartOS dashboard. Confirm SSH is enabled under System > SSH.
"Permission denied (publickey)"
start9@192.168.1.50: Permission denied (publickey).
Cause: The server does not recognize your key.
Fix: Confirm you added the public key (.pub file), not the private key, to StartOS. Check that you are pointing to the right private key with -i. Verify the username is start9. Check file permissions: chmod 600 ~/.ssh/id_ed25519_mynode
"Could not open a connection to your authentication agent"
Could not open a connection to your authentication agent.
Cause: ssh-add cannot find a running SSH agent.
Fix: On Windows, use the full path: C:\Windows\System32\OpenSSH\ssh-add.exe. On Mac/Linux, start the agent first: eval $(ssh-agent -s)
"Host key verification failed"
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
Cause: Your node's fingerprint changed since your last connection (reinstall, hardware swap).
If you know why it changed, remove the old entry: ssh-keygen -R 192.168.1.50. If you do not know why, investigate before connecting. This warning protects you from man-in-the-middle attacks.
"error: Could not connect to the server 127.0.0.1:8332"
Cause: Bitcoin Core is not running, or you ran bitcoin-cli outside the container.
Fix: Make sure you are using the podman exec prefix. Check if the container is running: sudo podman ps. Check Bitcoin Core's logs: sudo podman logs bitcoind.embassy --tail 20
"bitcoin-cli: command not found"
Cause: You are on the server shell, not inside the container.
Fix: Either exec into the container first (sudo podman exec -it bitcoind.embassy bash) or use the full podman exec command from the server shell.
Server Maintenance
# Check disk space
ssh mynode "df -h"
# Check running services
ssh mynode "sudo podman ps"
# View Bitcoin Core logs (last 20 lines)
ssh mynode "sudo podman logs bitcoind.embassy --tail 20"
# Restart Bitcoin Core (safe -- picks up where it left off)
ssh mynode "sudo podman restart bitcoind.embassy"
A full (unpruned) node uses 800+ GB and growing. If your drive fills up, Bitcoin Core will stop syncing.
When to Ask for Help
If you see errors about database corruption, unexpected shutdowns, or "block validation failed," do not try to fix these yourself. These are rare but serious.
Reference Links
- StartOS Community Support — Official forums for StartOS node operators
- Bitcoin Core Documentation — Official documentation for Bitcoin Core
- Bitcointalk Forums — Long-running Bitcoin discussion forum
- Bitcoin Wiki: Running Bitcoin — Community wiki on node operation