ObjBit
A complete, local-only, Bitcoin-inspired blockchain node written 100% in Objective-C — proof-of-work consensus, UTXO accounting, Merkle trees, difficulty retargeting, halving supply schedule, an encrypted HD-style wallet, a JSON-RPC daemon, and a colorful terminal client with a live dashboard.
No third-party dependencies. Foundation, CoreFoundation, CommonCrypto and
Security.framework only. Built with clang and a Makefile —
no Xcode project, no GUI.
ObjBit is deliberately incapable of external networking. The
daemon binds exclusively to 127.0.0.1, re-verifies every accepted
connection is loopback, opens no outbound sockets, and runs its own independent
chain with its own genesis block. It cannot talk to — and is not compatible
with — the real Bitcoin network.
Build
Requires macOS with the Xcode Command Line Tools.
make # builds build/objbitd and build/objbit-cli make test # full test suite incl. end-to-end (spawns a daemon) make test-asan # tests under AddressSanitizer + UndefinedBehaviorSanitizer make analyze # clang static analyzer (fails on any finding) make install # installs to /usr/local/bin (PREFIX=... to change) make dist # release tarball + SHA256SUMS make clean
Quickstart
objbitd & # first run creates ~/.objbit with sane defaults objbit-cli newwallet # pick a passphrase; you get your first address objbit-cli mine 10 # mine your first blocks (seconds on Apple Silicon) objbit-cli balance # coinbase rewards mature after 10 blocks objbit-cli send <addr> 1.5 # send 1.5 OBB (fees are estimated for you) objbit-cli mine # confirm it objbit-cli history # see everything that happened objbit-cli dashboard # live full-screen chain view — q to quit objbit-cli stop # cleanly stop the daemon
objbit-cli help shows the full command reference. All commands accept
--datadir=PATH, --port=N, and --no-color
(color also auto-disables when piped, and honors NO_COLOR).
Design at a glance
| Bitcoin | ObjBit | |
|---|---|---|
| Language | C++ | Objective-C, every line written for this project |
| Block time | 10 min | 30 s, smooth per-block EMA retarget |
| Supply | 21M, halving / 210k blocks | same schedule (50 OBB initial subsidy) |
| Signatures | ECDSA secp256k1 | ECDSA P-256 via Security.framework SecKey |
| Addresses | Base58Check(RIPEMD160(SHA256(pub))) | Base58Check(SHA256(pub)[0..20]), version 0x19 → addresses start with B |
| Script | Bitcoin Script | direct P2PKH-style pubkey-hash outputs (no script language) |
| Sighash | SIGHASH_ALL | ALL-style, additionally commits to the spent output's amount + pkh (BIP143-style) |
| Networking | P2P gossip | none — single local node, JSON-RPC on 127.0.0.1 only |
| Wallet | wallet.dat | AES-256-GCM encrypted, PBKDF2-HMAC-SHA256 · 600k rounds |
Architecture
One module per directory under src/:
src/crypto SHA-256, HMAC, PBKDF2, AES-256-GCM (GHASH implemented per
NIST SP 800-38D, validated against NIST vectors), Base58Check,
ECDSA verify, constant-time compare, secure zeroization
src/core transactions (UTXO model), blocks, Merkle tree, 256-bit
arithmetic, bounds-checked serialization, chain state +
validation engine with reorg support
src/consensus PoW check, per-block difficulty retarget, subsidy/halving,
deterministic genesis
src/storage append-only block log with per-record SHA-256 checksums and
crash recovery; atomic (write-temp-then-rename) UTXO snapshot
src/wallet SecKey P-256 keypairs, encrypted wallet file, addresses,
signing, export/import
src/node mempool (fee-ordered), GCD miner, JSON-RPC server
(token auth, rate limits), the node itself, JSON logging
src/cli terminal UI toolkit (24-bit color, box tables) + dashboard
tests/ pure-ObjC test runner: 220 checks, unit → consensus → e2e
Data lives in ~/.objbit (override with --datadir or
$OBJBIT_DATADIR): blocks.dat, utxo.dat,
wallet.dat (encrypted), token (RPC auth, 0600),
objbit.conf, objbitd.log (JSON lines),
mining_address.
RPC
JSON-RPC 2.0 over HTTP on 127.0.0.1:8465. Authenticate with the
token from ~/.objbit/token:
curl -s http://127.0.0.1:8465/ \
-H "Authorization: Bearer $(cat ~/.objbit/token)" \
-d '{"jsonrpc":"2.0","id":1,"method":"getstatus"}'
Methods: getstatus, getblock, getrecentblocks,
gettransaction, getmempool, getbalance,
getnewaddress, listaddresses, sendtoaddress,
history, estimatefee, generate,
minerstart, minerstop, walletcreate,
walletunlock, walletlock, walletexport,
walletimport, getpeers, stop.
Amounts are integer "bits" (1 OBB = 100,000,000 bits).
Security highlights
- RPC listener binds
127.0.0.1only; every accepted peer is re-verified as loopback; no outbound sockets exist anywhere in the daemon. - 32-byte auth token (0600) with constant-time comparison; strict JSON-RPC schema validation; 1 MiB request cap; rate limiting.
- Wallet encrypted with AES-256-GCM under a PBKDF2-HMAC-SHA256 (600k rounds) key; keys zeroized after use; auto-lock.
- All parsers bounds-checked and poison-on-failure; all amount arithmetic overflow-checked against the 21M cap.
- Zero-warning build under
-Wall -Wextra -Werror; clean ASan, UBSan and clang static analyzer runs.
The full threat model lives in SECURITY.md in the source tree,
design rationale in DECISIONS.md, and test coverage in
TESTING.md.
License
MIT. The release tarball ships the full text.