Module 8: Developing with Bitcoin Core Locally
Learning Objectives
By the end of this module, you will:
Build realistic Bitcoin development environments using regtest
Write scripts to simulate wallet activity and transaction flows
Mock confirmations, chain reorganizations, and mempool states
Understand when and how to separate your wallet and node services in production
Building Testing Environments Using Regtest
regtest is Bitcoin Core’s regression testing mode, designed for isolated, fully controlled environments.
You can:
Spin up a node without syncing to any peers
Mine blocks instantly
Generate unlimited test BTC
Simulate any transaction scenario
Use this environment to build and test:
Transaction pipelines
Webhooks and callbacks
Wallet-to-wallet transfers
Payment monitoring flows
A typical developer setup includes:
bitcoind -regtest -daemon
bitcoin-cli or a language-based RPC client
Optional scripts and mocks for block generation, fees, and UTXOs
Example bitcoin.conf for regtest development:
Writing Integration Scripts in Bash and Python
Bitcoin Core exposes a JSON-RPC interface, so any scripting language that supports HTTP requests can interact with it.
import requests
Use this setup to build:
CI tests
Sandbox payment flows
Automated funding or sweep logic
Mocking Confirmations and Network Events
Simulating Confirmations
Send a transaction:
Then confirm it instantly:
Check confirmation count:
Simulating Re-orgs
1. Invalidate a previously mined block:
2. Create a longer competing chain:
Use this to simulate:
Dropped/unconfirmed transactions
Edge case user experiences
Fallback logic for timeouts
Production Notes
When to Use a Pruned Node
A pruned node deletes historical block data but retains the full UTXO set and validates blocks.
Use pruning if:
You don’t need to inspect old transactions
You’re running lightweight infrastructure
You want to reduce disk usage (~1GB vs 500GB+)
Set in bitcoin.conf:
Pruned nodes still validate consensus and can serve most wallet operations.
Separating Wallet Logic from Node Logic
In production, it is often best practice to separate your wallet service from your full node for better security, performance, and scalability.
Benefits of Separation
Benefit | Description |
---|---|
Security | Wallet (private key logic) can be isolated from the public node. |
Multi-tenant Design | A single node can serve many wallets, improving scalability and separation. |
Performance | Reduces wallet-specific load on the node, enhancing performance. |
Modularization | Enables independent wallet upgrades, migrations, and redundancy setups. |
Compliance | Allows wallet services to integrate KYC, usage tracking, or user authentication separately. |
Example Workflow
Deposit Flow
App requests an address → Wallet service calls
Wallet signs → signrawtransactionwithwallet
Node broadcasts → sendrawtransaction
Withdrawal Flow
App prepares TX → Wallet service calls createrawtransaction
Wallet signs → signrawtransactionwithwallet
Node broadcasts → sendrawtransaction
Deployment Practices
Run wallet service on a locked-down server
Use disablewallet=1 on public-facing node
Use strict RPC credentials and IP allowlists
Consider separate Docker containers for each service
Monitor wallet usage and log signing events
Activity
Write a Bash or Python script that:
Starts a wallet
Mines 101 blocks
Sends BTC to 3 addresses
Confirms each transaction with block generation
Verifies balances
Modify the script to simulate:
A zero-conf state
A re-org scenario
Use of decoderawtransaction to verify TXs