GitBCH
Code as CashTokens NFTs on Bitcoin Cash mainnet. A specification of the protocol primitives, with the on-chain receipts that prove the model works.
Overview
GitBCH is a code repository protocol that uses CashTokens NFTs on Bitcoin Cash mainnet to anchor source code and its history. A Repo is a minting NFT. Each file commit is a child mutable NFT under that Repo’s category. File content is encoded into the same transaction as the mint, anchored by a BCMR-v2 hash registry. This document specifies the primitives and presents the on-chain receipts that prove the model works.
The protocol is small on purpose. Five composable patterns — documented in §4 — produce the rest: atomic repo creation, file lineage, tamper-evident metadata, and an authority model in which holdership of an NFT is the permission to write.
Protocol grammar
Every object on the network is identified by the first byte of its NFT commitment: the type tag. Resolvers dispatch on a single byte; wallets render the right detail sheet by tag; new tokens can be added without colliding with the registry.
Each token, in one sentence
- Repo — a minting NFT whose holder is the project owner. Every commit, edit, fork, and merge under the repo is authorized by spending or minting under this category.
- CashBit (File) — a mutable child NFT of a Repo whose commitment encodes the file path and content hash. Editing the file is a spend that produces a new mutable NFT under the same category, preserving lineage.
- Identity — a transferable mutable NFT representing a contributor profile. The NFT carries the profile, not the address.
- Reply — a mutable NFT representing a single message in a discussion. Cheap to mint, scoped to a parent reference, edited by spending.
- Thread (Issue) — a minting NFT representing an issue with a state machine: Open, In Progress, Resolved, Closed. Its mints are the state transitions.
- Bounty — a CashScript covenant, not an NFT, with time-locked cancellation. Lives under an Issue; pays out on owner approval.
- Pull Request — a CashBit (0x01) minted under a fork’s category with BCMR metadata flag type: 'pr'. Owner merge is a re-mint into the target Repo’s category by the holder of the target’s minting NFT. No new tag needed.
Mainnet proofs
Every claim that follows is grounded in a transaction you can fetch and verify. The receipts are public.
V1 era — ChunkDrip CashBits
Before the Repo + child-NFT model, GitBCH proved code-on-chain via the ChunkDrip covenant: a Mecenas-pattern non-custodial escrow that served raw OP_RETURN bytes paid for by anonymous QR. Two historic CashBits anchor the V1 era.
V2 era — the CashTokens NFT model
The V2 model promotes every project artifact to a CashTokens NFT. A Repo is a minting NFT; every CashBit is a mutable child of that minting authority. Three milestones land the model on mainnet end to end.
A repository and its first commit, including the file content, were created and confirmed in a single signature. There is no separate “init” step. The repo and its first byte exist together or not at all.
First Reply — the sign-only architecture, end to end
The dashboard built the unsigned transaction server-side, the wallet signed it (and only signed — broadcast was no longer the wallet’s job), the dashboard posted the signed bytes to the server, and the server broadcast through its own Fulcrum proxy. Browser-side chain queries played no role in the mint flow. This is the first transaction proving Pattern F (below) end to end on mainnet.
Bounty release — covenant unlock via BCH-WalletConnect
The release transaction spends a P2SH-20 covenant input. The dApp builds the unsigned transaction with cashscript’s TransactionBuilder.generateWcTransactionObject({}) per CHIP-2024-09 / BCH-WalletConnect; the sourceOutputs[i].contract hint on the contract input carries { abiFunction, redeemScript, artifact } so the wallet can re-derive the unlock script with the owner’s real pubkey and signature. The wallet signs the contract input with Schnorr and sighash 0x61. The covenant enforces the two-output structure on chain.
Architecture
Six patterns underlie everything above. They are deliberately small; the system gets its power from how cleanly they compose.
Pattern A — Genesis-with-child-mint
A CashTokens genesis transaction may emit any number of token outputs of the freshly-derived category. GitBCH uses this to mint the Repo’s minting NFT and the first file’s mutable NFT in the same transaction. The simultaneously-minted minting NFT establishes authority for the mutable NFT. One wallet signature creates the entire repo.
Pattern B — Chain-verified sidecar
The canonical metadata for a Repo is a BCMR-v2 registry hash-anchored on chain. Adding mint TXIDs to it after the fact would break the anchor. GitBCH uses a sidecar: a fast-lookup index alongside the BCMR, populated only by an endpoint that independently fetches the transaction, verifies the commitment matches, and only then writes the index. The client supplies a TXID as an optimization, never as truth.
Pattern C — ["$self"] chunks sentinel
File content lives as GCP-1 OP_RETURN chunks in the same transaction as the NFT mint. The BCMR records chunks: ["$self"] — a sentinel meaning “the resolver should substitute this transaction’s own ID at read-time.” This resolves the chicken-and-egg of needing the mint TXID to write a BCMR that gets anchored inside that mint. Any “mint-and-content in one TX” protocol can adopt this trick.
Pattern D — BCMR-v2 hash-anchored registry
Every Repo carries a tamper-evident registry that maps logical paths to content hashes, lineage, and metadata. The registry hash is committed to chain in the same transaction as the mint. Edits are verifiable. Rewrites are detectable.
Pattern E — Owner-as-minting-NFT-holder
Authority over a Repo is exactly the holdership of its minting NFT. To merge a pull request into a Repo, you spend the Repo’s minting NFT to mint the new child. To transfer the Repo, you transfer the NFT. There is no separate access-control system; the cryptography is the permission model.
Pattern F — Sign-only wallet, server broadcast
Holding keys and reaching the chain are different responsibilities with different failure modes. Wallets hold keys and sign. The dApp builds the transaction, broadcasts it, and tells the wallet what txid landed. When the chain-query layer is unreliable on either side, only one role is affected at a time, and the architecture absorbs it.
Concretely: a sign request reaches the wallet via CashNect, the wallet signs and returns { signedTransaction: hex }, the dApp posts that to its own broadcast endpoint, the dApp’s server submits to chain through a server-side Fulcrum proxy. A one-way broadcast_completed notification flows back so the wallet’s history can render the entry. Old wallets that still self-broadcast keep working unchanged — the protocol carries either a signed-transaction hex, a txid, or both.
GitBCH is live on Bitcoin Cash mainnet. The primitives in this document are the foundation.