181 lines
5.1 KiB
Markdown
181 lines
5.1 KiB
Markdown
# SHA-256 Miner (From Scratch, Python Starter)
|
|
|
|
A clean, production-minded **starting point** for building SHA-256 miners from scratch.
|
|
|
|
This repository provides a complete, readable Python implementation of a Bitcoin-style mining pipeline using `getblocktemplate` and JSON-RPC. It is intentionally written in Python to keep the architecture simple, inspectable, and easy to evolve.
|
|
|
|
## Positioning
|
|
|
|
This project is designed for engineers who want to:
|
|
- understand mining internals end-to-end
|
|
- customize nonce-search and block-building logic
|
|
- use a practical base before moving performance-critical parts to lower-level languages
|
|
|
|
This project is **not** an ASIC-grade miner and is **not** intended for profitable mainnet mining.
|
|
|
|
## What You Get
|
|
|
|
- End-to-end mining flow (`template -> coinbase -> merkle -> header -> PoW -> submit`)
|
|
- Multiprocess worker orchestration
|
|
- Worker-specific `extranonce2` generation
|
|
- SegWit-aware template processing
|
|
- Coinbase construction with custom message support
|
|
- Block serialization and submission to Bitcoin Core
|
|
- Watchdog-based restart on chain tip updates
|
|
- Live aggregated dashboard (attempts/hashrate by worker)
|
|
|
|
## Repository Layout
|
|
|
|
- `launcher.py`: supervisor, process lifecycle, dashboard
|
|
- `main.py`: single-worker mining loop
|
|
- `miner.py`: PoW nonce search engine
|
|
- `block_builder.py`: coinbase/header/block assembly
|
|
- `rpc.py`: Bitcoin Core RPC client helpers
|
|
- `utils.py`: hashing, target conversion, watchdog logic
|
|
- `config.py`: runtime configuration
|
|
- `config.py.example`: full configuration template
|
|
|
|
## Architecture Overview
|
|
|
|
1. `launcher.py` starts N worker processes.
|
|
2. Each worker requests a fresh block template from Bitcoin Core.
|
|
3. Coinbase is built using block height, optional message, `EXTRANONCE1`, and worker-specific `EXTRANONCE2`.
|
|
4. Merkle root and block header are assembled.
|
|
5. `miner.py` searches for a valid nonce according to the selected strategy.
|
|
6. If a valid header is found, the block is serialized and submitted.
|
|
7. Workers restart with a new template after successful submission or tip change.
|
|
|
|
## Requirements
|
|
|
|
- Python 3.10+
|
|
- Bitcoin Core node with RPC enabled
|
|
- Recommended network for development: `regtest`
|
|
|
|
Install:
|
|
|
|
```bash
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
## Bitcoin Core Setup
|
|
|
|
Example `bitcoin.conf` values:
|
|
|
|
```ini
|
|
server=1
|
|
rpcuser=user
|
|
rpcpassword=password
|
|
rpcallowip=127.0.0.1
|
|
rpcport=18443
|
|
regtest=1
|
|
```
|
|
|
|
Use values consistent with your local node and wallet setup.
|
|
|
|
## Configuration (`config.py`)
|
|
|
|
All runtime settings are defined in `config.py`.
|
|
Use `config.py.example` as the canonical template.
|
|
|
|
Minimal example:
|
|
|
|
```python
|
|
import multiprocessing as mp
|
|
|
|
# RPC
|
|
RPC_USER = "user"
|
|
RPC_PASSWORD = "password"
|
|
RPC_HOST = "127.0.0.1"
|
|
RPC_PORT = 8332
|
|
|
|
# Wallet
|
|
WALLET_ADDRESS = ""
|
|
|
|
# Mining
|
|
DIFFICULTY_FACTOR = 1.0
|
|
NONCE_MODE = "incremental" # incremental | random | mixed
|
|
TIMESTAMP_UPDATE_INTERVAL = 30
|
|
BATCH = 10_000
|
|
COINBASE_MESSAGE = "/py-miner/"
|
|
EXTRANONCE1 = "1234567890abcdef"
|
|
EXTRANONCE2 = "12341234"
|
|
|
|
# Workers
|
|
_NUM_PROCESSORS = 0
|
|
NUM_PROCESSORS = _NUM_PROCESSORS if _NUM_PROCESSORS > 0 else mp.cpu_count()
|
|
|
|
# Watchdog
|
|
CHECK_INTERVAL = 20
|
|
```
|
|
|
|
## Supported Configuration Behavior
|
|
|
|
- `NONCE_MODE`: must be `incremental`, `random`, or `mixed`
|
|
- `TIMESTAMP_UPDATE_INTERVAL`: seconds, `0` disables periodic timestamp updates
|
|
- `BATCH`: number of nonces per compute batch
|
|
- `NUM_PROCESSORS`:
|
|
- `> 0`: exact number of workers
|
|
- `<= 0`: auto CPU count
|
|
- `DIFFICULTY_FACTOR`:
|
|
- on `regtest`:
|
|
- `0`: keep original template target
|
|
- `> 0`: compute target as `max_target / factor`
|
|
- `< 0`: clamped to `0.1`
|
|
- on non-`regtest`: forced to `1.0`
|
|
|
|
## Run
|
|
|
|
Default:
|
|
|
|
```bash
|
|
python launcher.py
|
|
```
|
|
|
|
CLI options:
|
|
- `-n`, `--num-procs`: number of workers
|
|
- `--base-extranonce2`: base hex value for per-worker extranonce2 derivation
|
|
|
|
Example:
|
|
|
|
```bash
|
|
python launcher.py -n 4 --base-extranonce2 12341234
|
|
```
|
|
|
|
## Operational Notes
|
|
|
|
- `EXTRANONCE1` and `EXTRANONCE2` must be valid hex strings.
|
|
- Coinbase `scriptSig` must remain within protocol constraints (the implementation enforces a 100-byte limit).
|
|
- Invalid RPC credentials or invalid wallet address will fail at runtime.
|
|
|
|
## Tested Capacity
|
|
|
|
Reference test result for this miner implementation:
|
|
- Platform: Raspberry Pi 5
|
|
- CPU usage: 4 cores
|
|
- Observed throughput: **~1.8 MH/s**
|
|
|
|
Performance depends on clock profile, thermal conditions, operating system, and background load.
|
|
|
|
## Current Limits (By Design)
|
|
|
|
This is a Python starter implementation. It intentionally does not include:
|
|
- ASIC/GPU kernels
|
|
- Stratum server/client stack
|
|
- advanced failover/job persistence
|
|
- extensive benchmark/profiling harness
|
|
|
|
## Recommended Evolution Path
|
|
|
|
1. Add strict schema validation for `config.py`.
|
|
2. Add deterministic unit tests for block assembly and hashing paths.
|
|
3. Introduce microbenchmarks for nonce-loop and hashing batches.
|
|
4. Add integration tests against disposable `bitcoind` `regtest` nodes.
|
|
5. Extract core components into reusable packages (RPC, builder, PoW engine).
|
|
6. Move performance-critical sections to C/Rust/CUDA while preserving Python orchestration.
|
|
|
|
## License
|
|
|
|
MIT. See [LICENSE](LICENSE).
|