boha 0.10.0

Crypto bounties, puzzles and challenges data library
Documentation

boha

Ask DeepWiki CI autofix.ci

Crypto bounties, puzzles and challenges data library.

Installation

CLI

Arch Linux (AUR):

paru -S boha

From crates.io:

cargo install boha --features cli,balance

Library

[dependencies]
boha = "0.1"

With balance fetching:

[dependencies]
boha = { version = "0.1", features = ["balance"] }

Usage

CLI

# 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/66
boha show gsmg
boha show hash_collision/sha256

# Get key range
boha range 66

# Check balance (requires --features balance)
boha balance b1000/71

# Output formats (default: table)
boha -o json stats
boha -o yaml show b1000/66
boha -o csv list b1000 > puzzles.csv
boha -o jsonl list b1000 --unsolved | jq .

Output formats

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

Library

use boha::{b1000, gsmg, hash_collision, zden, Status};

let p66 = b1000::get(66).unwrap();
println!("Address: {}", p66.address);
println!("H160: {}", p66.h160.unwrap());
println!("Funded: {}", p66.start_date.unwrap_or("unknown"));

let range = p66.key_range().unwrap();
println!("Range: 0x{:x} - 0x{:x}", range.start(), range.end());

if let Some(txid) = p66.claim_txid() {
    println!("Claimed in: {}", txid);
    println!("Explorer: {}", p66.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/66").unwrap();
let puzzle = boha::get("gsmg").unwrap();
let puzzle = boha::get("zden/Level 1").unwrap();

Balance fetching (async)

use boha::{b1000, balance};

#[tokio::main]
async fn main() {
    let puzzle = b1000::get(71).unwrap();
    let bal = balance::fetch(puzzle.address).await.unwrap();
    
    println!("Confirmed: {} sats", bal.confirmed);
    println!("Total: {:.8} BTC", bal.total_btc());
}

Features

Feature Description
cli Command-line interface
balance Blockchain balance fetching via mempool.space API

Collections

b1000

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

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.

hash_collision

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

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

Data

All puzzle data is embedded at compile time from TOML files in data/.

Each puzzle includes: address, h160 (Hash160 for P2PKH addresses), status, BTC amount, public key (if exposed), solve date (if solved), and start date (when funded).

License

MIT