Crypto bounties, puzzles and challenges data library.
- Bitcointalk - Discussion thread
Arch Linux (AUR):
paru -S bohaFrom crates.io:
cargo install boha --features cli,balance[dependencies]
boha = "0.14"With balance fetching:
[dependencies]
boha = { version = "0.14", features = ["balance"] }# Statistics
boha stats
# List puzzles
boha list
boha list b1000
boha list b1000 --unsolved
boha list b1000 --with-pubkey
# Show puzzle details
boha show b1000/90
boha show gsmg
boha show hash_collision/sha256
# Show puzzle and open asset in browser
boha show zden/Level\ 4 --open
# Get key range
boha range 90
# Check balance (requires --features balance)
boha balance b1000/71
# Output formats (default: table)
boha -o json stats
boha -o yaml show b1000/90
boha -o csv list b1000 > puzzles.csv
boha -o jsonl list b1000 --unsolved | jq .| Format | Flag | Description |
|---|---|---|
table |
-o table |
TUI table with colors (default) |
json |
-o json |
Pretty-printed JSON |
jsonl |
-o jsonl |
JSON Lines (one object per line) |
yaml |
-o yaml |
YAML |
csv |
-o csv |
CSV with header |
use boha::{b1000, bitaps, gsmg, hash_collision, zden, Status};
let p90 = b1000::get(90).unwrap();
println!("Address: {}", p90.address.value);
println!("HASH160: {}", p90.address.hash160.unwrap());
println!("Funded: {}", p90.start_date.unwrap_or("unknown"));
let range = p90.key_range().unwrap();
println!("Range: 0x{:x} - 0x{:x}", range.start(), range.end());
if let Some(txid) = p90.claim_txid() {
println!("Claimed in: {}", txid);
println!("Explorer: {}", p90.chain.tx_explorer_url(txid));
}
let unsolved: Vec<_> = b1000::all()
.filter(|p| p.status == Status::Unsolved)
.filter(|p| p.pubkey.is_some())
.collect();
let gsmg_puzzle = gsmg::get();
let sha256 = hash_collision::get("sha256").unwrap();
let level1 = zden::get("Level 1").unwrap();
let puzzle = boha::get("b1000/90").unwrap();
let puzzle = boha::get("gsmg").unwrap();
let puzzle = boha::get("bitaps").unwrap();
let puzzle = boha::get("bitimage/kitten").unwrap();
let puzzle = boha::get("zden/Level 1").unwrap();
// Access puzzle assets (images, hints)
if let Some(path) = puzzle.asset_path() {
println!("Local: {}", path);
}
if let Some(url) = puzzle.asset_url() {
println!("Remote: {}", url);
}use boha::{b1000, balance};
#[tokio::main]
async fn main() {
let puzzle = b1000::get(71).unwrap();
let bal = balance::fetch(puzzle.address.value).await.unwrap();
println!("Confirmed: {} sats", bal.confirmed);
println!("Total: {:.8} BTC", bal.total_btc());
}| Feature | Description |
|---|---|
cli |
Command-line interface |
balance |
Blockchain balance fetching via mempool.space API |
Bitcoin Puzzle Transaction - 256 puzzles where each puzzle N has a private key in range [2^(N-1), 2^N - 1].
Solved (82): 1-70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130
Unsolved with public key (6): 135, 140, 145, 150, 155, 160
Unsolved (72): 71-74, 76-79, 81-84, 86-89, 91-94, 96-99, 101-104, 106-109, 111-114, 116-119, 121-124, 126-129, 131-134, 136-139, 141-144, 146-149, 151-154, 156-159
Empty - no funds (96): 161-256
GSMG.IO 5 BTC Puzzle - Multi-phase cryptographic challenge with a single Bitcoin address.
| Address | Status | Prize |
|---|---|---|
| 1GSMG1JC9wtdSwfwApgj2xcmJPAwx7prBe | Unsolved | ~1.25 BTC |
Originally 5 BTC, prize halves with each Bitcoin halving.
Peter Todd's hash collision bounties - P2SH addresses that can be claimed by finding hash collisions.
| Puzzle | Hash | Status | Prize |
|---|---|---|---|
| sha1 | SHA-1 | ✅ Claimed (2017-02-23) | 2.48 BTC |
| sha256 | SHA-256 | ⏳ Unsolved | 0.277 BTC |
| ripemd160 | RIPEMD-160 | ⏳ Unsolved | 0.116 BTC |
| hash160 | HASH160 | ⏳ Unsolved | 0.100 BTC |
| hash256 | HASH256 | ⏳ Unsolved | 0.100 BTC |
| op_abs | OP_ABS | ✅ Claimed (2013-09-13) | - |
Zden's Visual Crypto Puzzles - Artistic puzzles where private keys are encoded in images, animations, and visual patterns.
| Chain | Solved | Unsolved | Total |
|---|---|---|---|
| Bitcoin | 9 | 2 | 11 |
| Ethereum | 2 | 0 | 2 |
| Litecoin | 1 | 0 | 1 |
| Decred | 1 | 0 | 1 |
Unsolved: Level 5, Level HALV
Bitaps Mnemonic Challenge - Shamir Secret Sharing Scheme (SSSS) puzzle where the original 12-word mnemonic was split into 5 shares using 3-of-5 threshold.
| Address | Status | Prize |
|---|---|---|
| bc1qyjwa0tf0en4x09magpuwmt2smpsrlaxwn85lh6 | Unsolved | ~1.0 BTC |
Two of three required shares are published. Goal: break the SSSS scheme or find implementation bugs.
Bitimage puzzles - Bitcoin addresses derived from arbitrary files using SHA256(Base64(file)) as BIP39 entropy.
| Puzzle | Passphrase | Status | Prize |
|---|---|---|---|
| kitten | No | ✅ Solved (2019-07-09) | 0.00095 BTC |
| kitten_passphrase | Yes | ⏳ Unsolved | ~0.01 BTC |
Both puzzles use the same source file (Antonopoulos kitten tweet). The passphrase puzzle requires an unknown BIP39 passphrase.
All puzzle data is embedded at compile time from TOML files in data/.
Each puzzle includes: address (with HASH160 and type), chain, status, prize, public key (if exposed), private key (if solved), key source, solve date (if solved), solve time, start date (when funded), transactions history, solver information, and assets (puzzle images, hints).
Visual puzzle collections (zden, gsmg, bitimage) include embedded assets in assets/ directory:
assets/
├── zden/ # 15 puzzle images
├── gsmg/ # puzzle.png, follow_the_white_rabbit.png
└── bitimage/ # kitten images
Access via library:
let puzzle = zden::get("Level 4").unwrap();
println!("{}", puzzle.asset_path().unwrap()); // assets/zden/level-4/puzzle.png
println!("{}", puzzle.asset_url().unwrap()); // https://raw.githubusercontent.com/...| Tool | Description |
|---|---|
| vuke | Research tool for studying vulnerable Bitcoin key generation practices. Analyze solved puzzles for weak patterns. |
| vgen | Bitcoin vanity address generator with regex pattern matching and GPU acceleration. |
MIT