The Builder's Week: A Working Bitcoin Stack Appears, One Repository at a Time
What ten open-source repositories on a single GitHub account actually do, how they interlock, and why the honest parts matter more than the loud ones.
I have spent this week shipping, not describing. Here is the whole thing — the micro-payment engine, the audit-evidence system, the broadcast-encryption layer, and the dealerless card protocol — together with a plain account of every concept that makes them work. If a term appears, I explain it. I would rather you understand the machine than admire it.
Keywords: Bitcoin SV, BSV, sub-satoshi payments, payment channels, bonded channels, Merkle proofs, verifiable accounting, selective disclosure, triple-entry accounting, broadcast encryption, key-graph, logical key hierarchy, rekeying, ECIES, AEAD, threshold custody, mental poker, dealerless card games, post-Genesis script
Published: June 1, 2026
The world is overrun with men who describe the future and never build it. They have discovered that an announcement is cheap and a deliverable can be checked, and they have made their peace with the difference. I have no such peace to make. Over the past few days I have published, in the open, a set of repositories on Bitcoin SV that do — in running code, with tests that fail honestly — what the field has spent fifteen years promising. This essay is the guided tour. I will not ask you to trust me. I will explain each idea until you could rebuild it yourself, and then I will tell you exactly where it stops.
One principle governs everything below, and I want it stated before the first line of code: a builder’s honesty about limits is the strongest evidence for his claims. The system that tells you what it cannot do has understood itself; the system that claims everything has understood nothing. So each component here declares its own boundary in ink. The accounting system tells you it cannot detect a lie told at the source. The card protocol tells you its tokens are worth nothing. The channel runs in a test network by default and shouts at you before it will touch real money. That is not timidity. It is the only form of confidence that survives contact with reality.
Let me also dispatch a confusion that wastes more breath than any other in this subject. When I say Bitcoin, I mean the original protocol — the one that scales on-chain, restores the full script capability, and treats the chain itself as the foundation. That is BSV. It is not BTC, and the distinction is not tribal; it is technical, and it determines what you can build. Several of the designs below exist because the BTC approach is impossible on this chain, and I will show you precisely why when we reach it. Every line of code I have written is for BSV. There is no BTC code here, and there will never be.
Part I — The micro-payment engine: bonded sub-satoshi channels
Repository: github.com/prof-faustus/bonded-subsat-channel
The problem, stated exactly
A satoshi is the smallest unit Bitcoin records on-chain. There is no such thing as half a satoshi in a transaction output; the protocol counts in whole integers and nothing finer. This is not a defect — it is what makes the ledger exact — but it has a consequence. If you want to charge a tenth of a satoshi for an API call, or a thousandth of a satoshi per kilobyte of streamed video, the chain has no native way to express the amount, and even if it did, posting a separate transaction for each tiny charge would cost more in overhead than the charge is worth. The unit is too coarse and the per-transaction cost too high for the value you wish to move.
So the question is precise: how do you move a fraction of a satoshi, millions of times, without ever writing a fractional amount to the chain and without drowning the chain in transactions?
What a payment channel is
The general answer, known for years, is a payment channel. Two or more parties lock some funds in an opening transaction, then exchange signed updates off-chain that re-divide those funds between them. Each update is a fully valid transaction that could be broadcast, but normally is not. You might exchange ten thousand such updates — each one a new agreed division of the same locked pot — and only ever publish the last one to the chain when you close. The chain sees two transactions, the open and the close; the ten thousand re-divisions happened privately, at the speed of a network message and the cost of a signature. That is the whole idea: keep the running state off-chain, settle the final state on-chain.
The hard parts of a channel are always two: how do you make the amounts finer than the chain allows, and how do you stop a participant from cheating by broadcasting an old state that paid him more than the current one does?
My answer to fineness: subdivision with whole-satoshi settlement
I let you choose a granularity, k. A single funded satoshi is divided, off-chain only, into k micro-units. At k = 1000, one micro-unit is a thousandth of a satoshi. At k = 1,000,000, a millionth. Inside the channel you move these micro-units as freely as you like; the running ledger is kept in micro-units and never touches the chain.
When the channel finally settles, the chain must see whole satoshis — because that is all it can record. So I reconcile the micro-unit balances back to integer satoshis using a deterministic rule I call Q*. The mechanism is a largest-remainder method: each participant is owed some whole number of satoshis plus a fractional remainder; the whole numbers are paid out directly, and the leftover satoshis — there are always exactly as many leftover whole satoshis as the fractions sum to — are awarded, one at a time, to the participants with the largest remainders first. The result is the fairest integer division of the pot that exactly preserves the total, computed identically by every honest party because the rule is deterministic. No fractional output is ever written to the chain. The sub-satoshi precision lives entirely in the off-chain accounting; the chain only ever sees integers, exactly as it must.
My answer to cheating: a fixed one-satoshi bond, forfeited on a stale broadcast
Now the harder half. What stops a participant from broadcasting an old channel state — one that paid him more than the latest agreed state does? In the BTC design, the answer is a punishment branch enforced by in-script time delays, and I will explain in a moment why that machinery does not exist on this chain. My answer is economic, and it is structurally simpler.
Each participant posts a fixed bond of one satoshi. If anyone broadcasts a superseded (stale) state, that act forfeits the offender’s bond to the honest parties. The arithmetic of cheating is therefore settled in advance: the most a cheat can hope to claw back by lying is bounded, and against it he stakes a bond he is certain to lose the moment he tries. Honest cooperative settlement becomes the unique rational outcome — not because anyone is trusted, but because dishonesty is engineered to cost more than it can earn. This is the Randian point made in protocol: you do not appeal to men’s virtue; you arrange matters so that their self-interest and honesty point in the same direction, and then you let them be self-interested.
The property I value most here is that the risked capital is fixed at one satoshi per participant, independent of payment size or path length. In capital-hungry channel designs your exposure grows with how much you route; here it does not. You stake one satoshi and your risk is one satoshi, whether you move a thousand micro-units or a billion.
Why I use no in-script timelocks — and what that even means
This is the technical crux, and the place most commentary on BSV goes wrong, so I will be exact.
Bitcoin script contains two opcodes designed to enforce time conditions inside a locking script: OP_CHECKLOCKTIMEVERIFY (CLTV) and OP_CHECKSEQUENCEVERIFY (CSV). On the chains that use them, they let a script say “this output cannot be spent until a certain time” or “...until a certain number of blocks after it was confirmed.” The BTC Lightning design leans on exactly these: its anti-cheating penalty depends on a time window enforced in the script itself.
On post-Genesis BSV, those two opcodes are no-ops — they do nothing. “No-op” means the interpreter encounters the opcode and simply moves past it without effect, as if it were not there. A script that relies on CLTV or CSV to enforce a delay therefore enforces nothing. This is why the BTC penalty mechanism cannot be transplanted: its load-bearing beam is, on this chain, made of air.
So I never place an in-script timelock anywhere. Where timing is genuinely needed, I enforce it at the transaction level, using nLockTime and the input nSequence field under the original transaction-replacement rule — mechanisms that operate on the transaction as a whole rather than as opcodes inside the script, and that remain fully meaningful post-Genesis. Combined with the bond-forfeiture incentive, that is sufficient. The construction uses only primitives that still mean something here: integer outputs, transaction-level finality, the SIGHASH flags that determine which parts of a transaction a signature commits to, and locking scripts built from ordinary opcodes — hash-and-equality checks, signature checks, the IF/ELSE/ENDIF conditionals, and multi-signature checks. Nothing exotic, nothing that depends on a feature this chain does not have.
The detail that separates tested from flattered
Anyone can write a test that passes. The question is what the test actually exercises. Every spend in my suite is executed through the real Bitcoin Script interpreter, with Genesis rules switched on, evaluating the script exactly as a node would. I specifically refuse the common shortcut of “signature spot-checks” — verifying a signature in Python and declaring victory without running the script through the virtual machine at all. A spot-check tells you a signature is valid; it does not tell you the script accepts the spend. And critically, my negative tests — the cases that are supposed to fail — must fail inside the interpreter, not in some hand-written guard I wrapped around it. A guard tells you your guard works. The interpreter failing tells you the chain would reject it. That is the only test worth trusting.
There is also a second part to the package: a self-contained BSV system that runs on a single machine with no external services at all — an embedded node speaking the native peer-to-peer wire protocol, a proof-of-work header chain that selects the longest chain by cumulative work, a database-backed block and UTXO store, a mempool that detects conflicts under the original replacement rule, and a full hierarchical-deterministic wallet. I did not want the channel to assume a chain to run against; I wanted to ship one.
Run it
git clone https://github.com/prof-faustus/bonded-subsat-channel
cd bonded-subsat-channel
./scripts/quickstart.sh # venv, tests, mypy, bandit, the demo, the transcript
# the demo at fine granularity:
python scripts/tiny_transfers_demo.py --k 1000000 --transfers 1000
# the CLI:
channel open --parties 4 --k 1000 --funded 1 --bond 1
channel transfer --script transfers.json
channel close
channel contestedIt runs in regtest by default; mainnet is opt-in behind an explicit research-code flag. The whole flow takes about thirty seconds on a modern machine. Believe the banner.
Part II — Making it auditable: verifiable accounting
Three coordinated repositories:
verifiable-accounting (Rust) — github.com/prof-faustus/verifiable-accounting
verifiable-accounting-bsv (TypeScript) — github.com/prof-faustus/verifiable-accounting-bsv
verifiable-accounting-chain (TypeScript) — github.com/prof-faustus/verifiable-accounting-chain
Suppose you have moved value at the scale Part I makes possible. A regulator, a tax authority, or an auditor now asks you to prove the net result. The naive options are both bad: hand over everything, and you have destroyed your own and your counterparties’ privacy; hand over a summary, and you have proved nothing, because a summary is exactly what a liar would forge. I wanted a third option — prove a specific figure is genuine and anchored, while revealing nothing about any other figure. To explain how, I must first explain the one structure that makes it possible.
Merkle trees, from the ground up
A Merkle tree is a way of fingerprinting a large set of items with a single short value, such that you can later prove any one item belongs to the set without revealing the others. You start with your items — call them leaves — and you take a cryptographic hash of each one. A cryptographic hash is a function that turns any input into a fixed-length string in a way that is practically impossible to reverse and practically impossible to forge a collision for: change one bit of the input and the output changes unrecognisably. (Bitcoin uses double-SHA256 — the SHA-256 hash applied twice — and the BSV block tree has a specific rule for handling an odd number of nodes, duplicating the last one, plus careful handling of byte order; I test all of this against real BSV mainnet blocks, because a Merkle implementation that has not been checked against the actual chain is a guess.)
Having hashed the leaves, you pair them up and hash each pair together to form the next level. Then you pair those and hash again. You repeat until a single hash remains at the top: the Merkle root. That one value commits to the entire set. Now the magic: to prove that a particular leaf is in the tree, you do not reveal the other leaves. You reveal only the leaf in question and the handful of sibling hashes along the path from that leaf up to the root — the Merkle proof, also called the path. The verifier rehashes the leaf, combines it with each supplied sibling in turn, and checks that the computation arrives at the known root. If it does, the leaf is genuinely in the set; if anyone had altered the leaf, the recomputed root would not match. The cost of the proof grows only with the logarithm of the set size — a tree of a million leaves needs a proof of about twenty hashes — and the other leaves never appear.
Layer A: anchoring evidence on the chain
In verifiable-accounting, the first layer (it corresponds to the invention in patent WO 2022/100946 A1) proves that a target data item is present in a BSV block, using a Merkle proof whose root is the block header’s own merkleroot field. Every Bitcoin block header commits to a Merkle root of all the transactions in that block; verification rehashes from your leaf up to that header root, and the header itself sits in the validated chain of headers secured by proof-of-work. So the chain of trust runs: your record → its hash → the path → the block header’s Merkle root → the header chain → proof-of-work. Nothing in that chain requires you to trust me, the auditor, or any server. It terminates in the most expensively secured data structure in existence.
Layer B: selective disclosure, which is the privacy mechanism
The second layer (patent WO 2025/119666 A1) makes those proofs work at scale and is where the privacy lives. It shards the proof data into non-overlapping portions, indexes them by transaction attributes, and on a query returns only the fragment needed to verify the one item asked about. This is selective disclosure, and it is worth dwelling on what makes it private. When you reveal one leaf and its path, the sibling hashes you supply along the way are just hashes — opaque fingerprints that reveal nothing about the records they fingerprint. The auditor learns that your figure is genuine and anchored; he learns nothing whatsoever about any other record, because all he ever sees of them is meaningless hash output. The selective disclosure is the privacy. No additional cryptography is bolted on.
Over the disclosed records, five named accounting equations — the invoice total, the accounts-receivable roll-forward, debit-equals-credit, the bank reconciliation, and the VAT identity — are checked by direct recomputation. Not by a clever argument about hidden numbers, but by actually recomputing the arithmetic over the actual disclosed figures and confirming it holds.
Why I refuse zero-knowledge proofs here — a point of principle
I could have reached for the fashionable tools: commitment schemes, zero-knowledge proofs, range proofs. I deliberately did not, and the reason is the entire philosophy of the system. Those tools prove a relationship among concealed numbers — they let you prove “the hidden value is positive” or “these two hidden values sum to that hidden value” without revealing the numbers. That is a marvel of cryptography, and it is not audit evidence, because the genuine record is never produced. An auditor’s job is not to be convinced that some concealed number satisfies a relation; it is to examine the actual record. Selective disclosure produces the genuine record — the real field, with proof that it is committed and anchored. That is the whole mechanism, and it is the right one, because audit is the production of examinable truth, not the performance of confidence about hidden things.
Triple-entry accounting, and the chain that links every record
To understand the third repository you need to understand double-entry accounting first. For five centuries the discipline has recorded every transaction twice — as a debit in one account and a matching credit in another — so the books stay in balance and an error shows up as an imbalance. Its weakness is that the two entries live in one party’s books, which that party can alter. Triple-entry accounting adds a third record that both sides reference — a shared entry neither can unilaterally change. On a blockchain, the chain is the natural home for that third record.
The verifiable-accounting-chain repository builds this on three pillars. First, a public-key-infrastructure root and a general-ledger key hierarchy: a single certified root key anchors the entity’s whole accounting structure, with a deterministic sub-key for every ledger node and field. “Deterministic derivation” means the keys are generated by a fixed mathematical rule from the root, and — crucially — the rule works such that the public side can be derived to match the private side without exposing the private keys. Second, an ECDH-linked, spend-linked, signed transaction chain: each accounting transaction actually spends the previous one and carries a signature from a key derived from its predecessor and the root, so that reordering, inserting, or dropping any transaction breaks the cryptographic links and is detected. (ECDH — Elliptic-Curve Diffie–Hellman — is the standard method by which two parties’ keys combine to derive a shared secret; here it is used to derive the linking keys.) Third, per-field selective disclosure over the field tree, exactly as in Layer B. On top of those pillars the system is mapped — every field has a ledger path — triple-entry, and tax-linked, so that a tax position recomputes from its mapped fields rather than being asserted.
The worked scenario shows the point. An auditor asks one narrow question: show me the VAT total for the period, and prove it matches the on-chain root. I produce a small bundle — the disclosed field, the Merkle path proving it belongs to the transaction’s committed field-tree root, the chain evidence binding that transaction into the root-anchored provable chain, and the inclusion proof anchoring the whole thing on BSV. The auditor verifies it independently and learns the figure is genuine, committed, mapped, chained, and anchored — and learns nothing about any other field or record.
A technical choice worth naming: pushdata, never OP_RETURN
The Merkle root is carried inside a BSV transaction as pushdata in the script — data pushed onto the stack as part of a real, spendable script — rather than in an OP_RETURN output. OP_RETURN marks an output as provably unspendable, a dead-end for storing data. Carrying the commitment as pushdata in a live script keeps the evidence inside the spendable, chainable transaction graph, which is what lets the spend-linking work. It is a small decision with large consequences, and it is the kind of decision that only matters if you are actually building the thing.
The boundary — and why it is the most important paragraph here
Read this twice, because it is where I refuse to flatter the work. The system establishes, over the disclosed records: inclusion (the leaf is in the anchored tree), integrity (the hash of the record bytes equals the leaf), selective disclosure (only the queried record is revealed; the rest remain opaque sibling hashes), and arithmetic correctness (the named equations hold when recomputed). It does not establish that the values are truthful, that any economic event actually occurred, that the classification is correct, that the population is complete without separate controls, or that anything is legally enforceable.
And the sharpest edge: a record entered falsely at origin, inside an otherwise internally consistent set of books, is not detected. The system does not solve the garbage-in problem, and I will not pretend it does. I assert this boundary in the source code itself, so that no one — including a future, more excitable version of me — can quietly paper over it. The default verification mode is the adversarial one, the only mode that yields independent audit evidence by ordinary Merkle reconstruction terminating in the header chain. A second “trusted-operational” mode exists but is off by default, opt-in only, and is never accepted on the audit path, because it does not produce independent evidence. I built the refusal into the machine.
Run it
# Rust core
cargo build --workspace --release && cargo test --workspace
cargo run -p vaa-cli -- selftest
cargo run -p vaa-cli -- reproduce # regenerate committed vectors; non-zero on mismatch
cargo run -p vaa-cli -- prove --records records.json --index 17 --out /tmp/bundle.json
cargo run -p vaa-cli -- verify --bundle /tmp/bundle.json
# TypeScript variants
npm ci && npm run build
node packages/cli/dist/index.js selftest
node packages/cli/dist/index.js reproducePart III — Controlling who can read: overlay broadcast encryption
Repository: github.com/prof-faustus/overlay-broadcast
This is the piece I am asked about most, and the one most people have never seen explained properly. So I will start with the problem in its simplest form and build up.
What broadcast encryption is, and why it is hard
Broadcast encryption is the problem of encrypting a message once so that exactly a chosen group of recipients can decrypt it, while everyone else — including former members and would-be eavesdroppers — cannot. Think of a paid channel, an encrypted file shared with a team, or a content feed with subscribers. The encryption itself is easy; the difficulty is membership change.
Consider the two naive approaches and watch them both fail. Approach one: encrypt the message separately to each member’s personal key. This works, but the cost scales with the number of members — encrypt to a thousand members and you do a thousand encryptions per message, and every membership change is another full pass. That is the linear cost, written O(n), and it does not scale. Approach two: give everyone a single shared group key. Now encryption is cheap — one operation — but the moment you need to remove someone, you must change the shared key and securely redistribute the new one to every remaining member, because the removed member knows the old key. You are back to a per-member cost on every revocation, and worse, revocation is the operation you most need to be cheap.
The key-graph, also called the Logical Key Hierarchy
The elegant answer, which my broadcast layer implements (it realises the invention in patent GB 2623780 B), is to arrange the keys as a tree — a key-graph. Picture a balanced binary tree. At the root sits the message key, the key that actually decrypts the broadcast. At each leaf sits one user’s personal key. The internal nodes hold subgroup keys. Every child key is encrypted (”wrapped”) under its parent, so that knowing a node’s key lets you unwrap its parent, and so on up to the root. Each user is given the keys along the single path from their leaf up to the root — their leaf key, and the wrapped keys that let them climb. A member decrypts by climbing their path: leaf key unwraps the parent, which unwraps its parent, until they reach the message key at the top.
Now watch revocation become cheap. To remove a member, you do not touch everyone. You change only the keys on the removed member’s path — their leaf is abandoned, and each key from there to the root is replaced. Then you must inform the remaining members of the changed keys, but only those whose paths shared nodes with the removed member need anything, and each can be handed the new keys wrapped under keys they still hold. The total work scales with the logarithm of the group size — O(log n) — not with the group size itself. For a group of a thousand, that is roughly ten operations instead of a thousand. This logarithmic rekeying is the entire reason the structure exists, and it is the difference between revocation that is theoretical and revocation that is practical.
“Wrapping” a key, since I have used the word, means encrypting one key under another using an authenticated key-wrap — an encryption that not only conceals the wrapped key but lets the recipient detect if it has been tampered with. I never use raw exclusive-or to combine keys; I use authenticated encryption throughout, because an unauthenticated combination is an invitation to an attacker to flip bits undetected.
My broadcast layer offers three rekeying strategies, which are different ways of packaging those update messages (the classic Logical-Key-Hierarchy variants): user-oriented, one communiqué per affected user; key-oriented, one communiqué per changed key; and group-oriented, communiqués grouped by the key they are encrypted under. Which is most efficient depends on the shape of the membership change, and so I implement all three rather than pretend one is universally best.
The overlay layer: deriving keys from position, and signalling nothing
The second invention in this repository (patent EP 4 046 048 B1) lays the key-graph over ordinary BSV data-storage transactions, and it adds a property I find genuinely beautiful. A node’s key is re-derivable from its position in the graph plus a seed, using child key derivation — the standard mechanism (the same family used by hierarchical-deterministic wallets) by which a parent key and an index deterministically produce a child key. Because the key follows from position-plus-seed, a sender who wants a receiver to use a particular key need not transmit the key at all: he transmits only the position, and the receiver, who holds the seed, re-derives the key locally. I call this seed-isolated signalling, and its consequence is that no key material ever crosses the wire. An eavesdropper who captures every message captures only positions — coordinates with no meaning absent the seed.
At each node, three function key sets act, each with a distinct job: a writing key set authorises writing the node’s data-storage transaction; an obfuscation key set protects the node’s payload using authenticated encryption; and an application key set is the function the application itself cares about. Separating these means a key that can, say, read a payload cannot necessarily author a transaction — the principle of least authority, enforced by construction.
The cryptography underneath, named and explained
Two kinds of key do two kinds of work. Asymmetric keys — public/private key pairs on the secp256k1 curve, the same curve Bitcoin uses — sign transactions and seed the encryption handshakes. They are derived by child key derivation, so the whole hierarchy follows from a root. Symmetric keys — AES-256-GCM — do the bulk encryption of payloads, broadcast messages, and wrapped child keys. The division of labour is the classic one: asymmetric cryptography establishes a shared secret between parties who have never met; symmetric cryptography then bulk-encrypts efficiently using it.
Two acronyms deserve unpacking. AEAD — Authenticated Encryption with Associated Data — means an encryption that provides both confidentiality and integrity: the recipient not only recovers the plaintext but is guaranteed it was not altered, and that any associated context (a header, say) is bound to it. AES-256-GCM is the AEAD scheme I use. ECIES — the Elliptic Curve Integrated Encryption Scheme — is how I encrypt to a public key: the sender combines an ephemeral key of their own with the recipient’s public key via ECDH to derive a shared secret, runs it through a key-derivation function, and uses the result to symmetrically encrypt the message under AEAD. It is the standard, well-analysed way to send a confidential message to the holder of an elliptic-curve public key.
Custody: never holding the whole key in one place
The root of all this is the message key, and a single key held whole in one place is a single point of catastrophe. So custody uses threshold schemes — FROST and GG20 — in which the key is split into shares such that any sufficient subset (a threshold, say two of three) can act together, but no individual share, and no number of shares below the threshold, reveals anything. The key need never exist whole in one location; it is reconstructed, or used to sign, only by cooperation of the threshold. This is the cryptographic expression of a simple prudence: do not let any one failure, theft, or coercion be fatal.
Sessions, subscriptions, and revocation as an on-chain fact
A subscription funds k sessions. In the off-chain mode, a single on-chain funding transaction covers all k sessions, with sub-sessions split off-chain; in the on-block mode, one transaction anchors each session. Renewal spends the member’s output. And here is the property I am proudest of: an unspent output past its expiry is revocation. Access does not depend on a platform deciding you still belong. It depends on whether an output was spent in time — a fact written on the chain, verifiable by anyone, decided by no one.
The application I am often asked about — stated as exactly what it is
People ask whether this finally makes “useful NFTs” and revocable paid content possible. I will draw the line precisely, because the line is where honesty lives. What the repository is: key-graph broadcast encryption with an on-chain session lifecycle and revocation-by-non-renewal. That is a primitive — a foundation.
What you can build on it — an application, which I have not shipped as a finished product — is access-controlled content. Encrypt a file once with a symmetric key. Store the ciphertext anywhere you like — a server, a content-addressed store, on-chain. Open an overlay session whose key-graph hands each authorised user the derivation path they need; each climbs their path to recover the content key and decrypts. Add or remove members with a rekey, in logarithmic cost, without ever re-encrypting the original file. A token could carry a pointer to the ciphertext and the session identifier; access then becomes a cryptographic fact rather than a platform’s permission; revocation becomes an on-chain event anyone can verify; and, married to the Part I channel, “pay a fraction of a satoshi to join the access group” becomes mechanically simple. That is a genuinely strong design for paywalled content and shared, revocable archives — but it is a design you assemble from these primitives. The primitive is real and finished; the polished product is yours to build, and I will not dress the one up as the other.
Run it
cargo build --release
cargo run --release --bin overlay-broadcast -- selftest
cargo run --release --bin overlay-broadcast -- custody keygen --threshold 2 --shares 3
cargo run --release --bin overlay-broadcast -- broadcast open --users 1,2,3,4
cargo run --release --bin overlay-broadcast -- reproduce
# hardened, sandboxed:
docker run --rm --read-only --cap-drop ALL overlay-broadcast selftestIt is graded to flight-software standards — NPR 7150.2 and the JPL “Power of Ten” rules — with a full requirements-traceability matrix mapping every requirement to the code that satisfies it. I build key-management software the way one builds avionics, because the failure modes are comparably unforgiving.
Part IV — Proving the primitives carry an application: cardtable
Repository: github.com/prof-faustus/cardtable
The mental-poker problem
Here is a question older than blockchains: can a group of mutually distrustful players play a card game fairly, over a network, with no trusted dealer — and each verify that no one cheated? This is the mental poker problem, and it is harder than it sounds. A dealer must shuffle a deck no one can predict, deal cards no one but the holder can see, and yet the whole thing must be verifiable after the fact, with no central party anyone has to trust. Remove the trusted dealer and every easy assumption collapses.
The cryptographic answer, in outline, is a verifiable distributed shuffle. Each player encrypts the deck under their own key and shuffles it, then passes it on; after every player has had a turn, the deck is shuffled by the composition of everyone’s secret permutations — so no single player knows the order — and encrypted under everyone’s keys, so no single player can read a card. Revealing a card is then a matter of the relevant players releasing the right keys; and because each shuffle step can be accompanied by a proof that it was a genuine permutation rather than a swap-in of marked cards, the whole process is verifiable. Randomness for the shuffle is fixed by commit-and-reveal: each player first commits to a random value (publishes a hash of it, binding themselves without revealing it), and only later reveals it, so no one can choose their “randomness” after seeing anyone else’s.
My contribution: a transaction-native state machine
What I have built makes every one of these steps a real BSV transaction. cardtable is a transaction-native, peer-to-peer, non-custodial protocol where every game event is a signed transaction and every game state is a committed UTXO with exactly two successors: one cooperative branch for when everyone behaves, and one timeout-default branch for when someone disconnects or stalls. Every failure mode — a dropped connection, a refusal to reveal, an attempt to cheat — resolves to a deterministic on-chain consequence rather than an operator’s judgement call. There is no referee to bribe or to blame; the protocol’s branches decide, and the chain records the decision. Cards are concealed as encrypted card UTXOs; a player can fold without revealing their hand; and the entire round can be recorded as a transcript and re-verified offline afterwards. The first target game is In-Between (Acey-Deucey), but the primitives — the verifiable shuffle, the commit-reveal entropy, the encrypted-card UTXOs, the deterministic fallback graph — are general.
The repository holds itself to the same discipline as the rest of the stack: build only to BSV consensus and the post-Genesis opcode set; keep timelocks at the transaction level, never in-script; zero fabrication, with every number tracing to a source or marked as a tracked assumption; and no silent assumptions, declared on the face of the document. Its tokens carry no external monetary value, and it is explicit that it is not a regulated gambling product — the point is the protocol, not the stakes.
Status, plainly: the protocol is fully specified, and the non-on-chain cryptography and simulation layers are runnable; the early build phases are substantively in place and the full multi-card game is partial. It is research code in active construction, and I would rather you read it as a working specification with a growing implementation than as a finished consumer product.
How the stack composes
Read apart, these are four pieces of engineering. Read together, they are a single argument made in code:
bonded-subsat-channel moves tiny value at scale — off-chain, fixed-risk, settled in whole satoshis.
the verifiable-accounting family turns disclosed records into examinable, anchored audit evidence — and refuses, in its own source, to claim more than inclusion, integrity, selective disclosure, and arithmetic.
overlay-broadcast decides who may decrypt what, with logarithmic rekeying and revocation expressed as an on-chain fact.
cardtable shows the same transaction-native primitives carrying a real multiplayer application.
Every component terminates its trust in the validated block-header chain. Every component routes around the dead post-Genesis opcodes rather than pretending they still work. And every component states its boundary as part of its specification. That last habit is not decoration; it is the thing that makes the rest believable.
How this differs from what already exists
The Lightning Network (a BTC system)
Lightning is a capable design for BTC, and it is not a fair comparison transplanted here, because its anti-cheating penalty depends on the in-script timelock opcodes that are no-ops on post-Genesis BSV. My bonded channel is the native alternative: a fixed one-satoshi bond instead of capital that grows with throughput, transaction-level timing instead of in-script timelocks, and true sub-satoshi granularity off-chain with integer-only settlement on-chain. A different chain, with different primitives, demands a different design — and this one does not require the parts of BTC that simply do not exist here.
NFTs on Ethereum, Solana, and the rest
The prevailing pattern is “trust the platform” or “the file is public the instant it is revealed,” with revocation rare and clumsy where it exists at all. The overlay-broadcast primitive offers the opposite shape — cryptographic, on-chain, verifiable access control, with revocation as an unspent expiring output — at this chain’s fee profile rather than a congested one’s. The primitive is here; the product is for a builder to assemble.
Centralised paywalls — Substack, Patreon, and their like
Convenient, and wholly dependent on a third party who holds the keys, owns the relationship, and keeps the off-switch. The honest trade they offer is convenience now for ownership never. The overlay-broadcast approach lets a creator hold the access layer directly, on-chain. Whether that is worth the loss of convenience is a judgement each creator should make with open eyes — which is precisely the freedom the centralised model removes.
Limitations — stated without flinching
These are research prototypes. They run in test networks by default and warn, in capitals, against real funds. Believe the warning.
The accounting system cannot detect a lie at origin. It proves inclusion, integrity, selective disclosure, and arithmetic over disclosed records. It does not prove the figures are true, that events occurred, that classification is right, that the population is complete, or that anything is legally enforceable. Garbage in remains garbage — anchored, provable, and still garbage.
The integration glue is manual. There is not yet a single full-stack demonstration wiring payments, accounting, access control, and applications into one runnable whole. The pieces compose in principle; you assemble them in practice.
cardtable’s full game is still partial. The specification is complete and the lower layers run; the multi-card game is in progress.
This is one author’s work. High velocity and a single coherent vision on one side; concentrated key-person risk on the other. Both are true at once, and I will not hide the second to flatter the first.
The experience is command-line-first. These are primitives and reference implementations, not consumer applications. Polished interfaces, if they come, come later.
Why I bother
The market is loud with men who narrate the future and silent on the labour of making it, and they have grown comfortable in the gap, because narration is free and a working artefact can be checked. I have never been comfortable in that gap. The difference between describing a thing and building it is the only difference that has ever mattered, and the whole of this stack is an insistence on that difference. You can clone every line of it. You can run the tests and watch the negative cases fail inside the interpreter, where reality lives, rather than in some flattering wrapper I wrote to reassure you. You can regenerate every reported number from committed vectors that exit non-zero the moment they disagree. Nothing here asks for your faith.
What I have built is a coherent, open, BSV-native foundation for the things this technology was always supposed to make possible and somehow never did: micro-value that does not flood the chain, accounting evidence an auditor can verify and that declines to overstate itself, group key-management with revocation written on-chain for anyone to check, and transaction-native state machines that can carry a real application. It is early. It is the work of one hand. It is foundations, not a finished house. But it is real — and in a field that has spent fifteen years confusing the description of a thing with the thing itself, the real is not a small virtue. It is the only one.
I will keep building, and I will keep publishing as I go. If you build on Bitcoin — the original protocol — or merely wish to see what building looks like when it is done in the open and without apology, the hour to start cloning is now.
All links (current as of June 1, 2026)
Bonded Sub-Satoshi Channel — github.com/prof-faustus/bonded-subsat-channel
Verifiable Accounting (Rust) — github.com/prof-faustus/verifiable-accounting
Verifiable Accounting BSV (TypeScript) — github.com/prof-faustus/verifiable-accounting-bsv
Verifiable Accounting Chain (TypeScript) — github.com/prof-faustus/verifiable-accounting-chain
Cardtable (mental poker / dealerless games) — github.com/prof-faustus/cardtable
Overlay-Broadcast (key-graph + secure group access) — github.com/prof-faustus/overlay-broadcast



Is it technically possible to create a TEE (trust execution environment) on the user's own device, like a code execution "black box"?
From your text "Layer A: anchoring evidence on the chain
In verifiable-accounting, the first layer (it corresponds to the invention in patent WO 2022/100946 A1) proves that a target data item is present in a BSV block, using a Merkle proof whose root is the block header’s own merkleroot field. Every Bitcoin block header commits to a Merkle root of all the transactions in that block; verification rehashes from your leaf up to that header root, and the header itself sits in the validated chain of headers secured by proof-of-work. So the chain of trust runs: your record → its hash → the path → the block header’s Merkle root → the header chain → proof-of-work. Nothing in that chain requires you to trust me, the auditor, or any server. It terminates in the most expensively secured data structure in existence."
Very interesting! I hadn't thought of it like that.