bitcoincoding.dev / Experiments

Answers Bob McElrath · Braidpool

Rolling coinbase aggregation

An answer, on chain, to Bob McElrath's covenant challenge for Braidpool: each new coinbase joins the pool through a two-input APO update, and only the latest CTV payout can settle.

2026 · 04Inquisition signet✓ 6 tx confirmed61/61 checks passed

The question

Braidpool, a decentralized mining pool, has to hold coinbase rewards across many blocks before paying miners. Bob McElrath proposed a FROST federation that signs two chained transactions: the Rolling Coinbase Aggregation (RCA), which folds each new coinbase into the pool, and the Unspent Hasher Payout Object (UHPO), which pays everyone in proportion to work.

He then asked covenant proposers for an alternative that removes custody, so that only the correct payouts can happen.

What was built

How it works

RCA vN  (P2TR, three leaves)
  ctv_uhpo     <template_hash> OP_CHECKTEMPLATEVERIFY    # this period's payout
  apo_update   <0x01 || xonly_pubkey> OP_CHECKSIG         # next RCA replaces this one
  csv_escape   <2> OP_CSV OP_DROP <pk> OP_CHECKSIG        # timeout fallback

aggregation round:
  input 0  RCA v(N-1)     script path, APO signature (0x41)
  input 1  new coinbase   key path
  output   RCA vN = sum of inputs - fee

APO handles the input side (the next state can be signed without the previous txid); CTV handles the output side (each RCA commits to the current payout). Dynamic payouts come from a sequence of static commitments.

On chain

StepTransactionBlockNote
Block #1 coinbase → RCA v17557c229…5f7c29989432,750 sats
Block #2 coinbase600b9c7f…f06329989433,750 sats
Aggregation round 2 → RCA v2094a8aa1…ea9f299894pool 63,500 sats
Block #3 coinbase1bac7966…ea0c29989432,250 sats
Aggregation round 3 → RCA v301a00ecb…3206299894pool 92,750 sats
CTV settlement of v37669e251…de5a29989440,387 / 31,412 / 17,951 sats

Check it yourself

The repository re-checks every claim on this page (no keys, no node).

git clone https://github.com/aaron-recompile/braidpool-rca-covenant
cd braidpool-rca-covenant
python3 verify_onchain.py
61/61 checks passed

What it does not show

Sources

Technical record · facts.json
{
  "page": "https://bitcoincoding.dev/experiments/braidpool-rca/",
  "title": "Rolling coinbase aggregation",
  "context": "Answers Bob McElrath · Braidpool",
  "author": "Aaron Zhang (Aaron Recompile)",
  "date": "2026-04-15",
  "network": "Bitcoin Inquisition signet",
  "summary": "An answer, on chain, to Bob McElrath's covenant challenge for Braidpool: each new coinbase joins the pool through a two-input APO update, and only the latest CTV payout can settle.",
  "transactions": [
    {
      "role": "Block #1 coinbase → RCA v1",
      "txid": "7557c229f29771410307055fabf907e4263899c140ff1963a81868c2ea7f5f7c",
      "block": 299894,
      "explorer": "https://mempool.space/signet/tx/7557c229f29771410307055fabf907e4263899c140ff1963a81868c2ea7f5f7c",
      "note": "32,750 sats"
    },
    {
      "role": "Block #2 coinbase",
      "txid": "600b9c7f990ce09b7bfc06406d9f9e8d75696f44b86069974abb81b5dc5bf063",
      "block": 299894,
      "explorer": "https://mempool.space/signet/tx/600b9c7f990ce09b7bfc06406d9f9e8d75696f44b86069974abb81b5dc5bf063",
      "note": "33,750 sats"
    },
    {
      "role": "Aggregation round 2 → RCA v2",
      "txid": "094a8aa1d572ac76d5f012ce6cb31f9cb9f4e982e9e90604e96b551c07d5ea9f",
      "block": 299894,
      "explorer": "https://mempool.space/signet/tx/094a8aa1d572ac76d5f012ce6cb31f9cb9f4e982e9e90604e96b551c07d5ea9f",
      "note": "pool 63,500 sats"
    },
    {
      "role": "Block #3 coinbase",
      "txid": "1bac796632961eb18f8e50db0b643862cf7c8f6923fe27068a29b760a3e1ea0c",
      "block": 299894,
      "explorer": "https://mempool.space/signet/tx/1bac796632961eb18f8e50db0b643862cf7c8f6923fe27068a29b760a3e1ea0c",
      "note": "32,250 sats"
    },
    {
      "role": "Aggregation round 3 → RCA v3",
      "txid": "01a00ecba14dac6e60181f925bf2612dc9061d5791196a03270ccacfb4193206",
      "block": 299894,
      "explorer": "https://mempool.space/signet/tx/01a00ecba14dac6e60181f925bf2612dc9061d5791196a03270ccacfb4193206",
      "note": "pool 92,750 sats"
    },
    {
      "role": "CTV settlement of v3",
      "txid": "7669e2519776a6af8ac3317ba64324282d3c14188256c0ef64dac5500800de5a",
      "block": 299894,
      "explorer": "https://mempool.space/signet/tx/7669e2519776a6af8ac3317ba64324282d3c14188256c0ef64dac5500800de5a",
      "note": "40,387 / 31,412 / 17,951 sats"
    }
  ],
  "verify": {
    "repository": "https://github.com/aaron-recompile/braidpool-rca-covenant",
    "command": "python3 verify_onchain.py",
    "result": "61/61 checks passed",
    "needs": "no keys, no node"
  },
  "does_not_show": [
    "No FROST federation, share accounting or Braidpool DAG.",
    "One demo key signs everything; the coinbases are wallet-funded stand-ins without coinbase maturity.",
    "The CSV leaf is committed but not spent; signing is sequential.",
    "Signet scale: 10,000 sats stand for 1 BTC."
  ],
  "sources": [
    {
      "title": "Delving Bitcoin · Challenge: Covenants for Braidpool (Bob McElrath)",
      "url": "https://delvingbitcoin.org/t/challenge-covenants-for-braidpool/1370"
    },
    {
      "title": "Delving Bitcoin · reply #2: the RCA tree, APO rebinding and the state chain",
      "url": "https://delvingbitcoin.org/t/challenge-covenants-for-braidpool/1370/2"
    },
    {
      "title": "Delving Bitcoin · reply #4: dynamic coinbase aggregation with growing amounts",
      "url": "https://delvingbitcoin.org/t/challenge-covenants-for-braidpool/1370/4"
    }
  ]
}