Protocol dossier

A record that means nothing
until its other half lands.

Tandem is an original Bitcoin Universe protocol. It defines one on-chain object whose every state change requires a matched pair of authorizations. Half a pair is not a weaker version of the record. It is not a record at all.

Protocol finalized. Mainnet is not active.

In plain language

Two halves, one record

Most Bitcoin metaprotocols let one holder move one thing. Tandem does not. A Tandem object lives in a Bitcoin output that can only be spent when two specific keys both sign. The protocol layer then insists that the spend has the exact shape of one of five defined operations. Miss either requirement and there is no Tandem record.

SIDE A The first half

One participant key. It authorizes an input, receives an output, and is committed to by the carrier script. On its own it can do nothing to the object.

SIDE B The second half

The counterpart key. Sorted after side A by raw byte order, so the pair has one unambiguous written form. On its own it can do nothing to the object either.

The pairing requirement is not a policy that some service enforces. It is the shape of the Bitcoin output itself: an exact 71-byte 2-of-2 witness script, wrapped in native P2WSH. Bitcoin consensus refuses an unmatched spend before any Tandem software is consulted. Tandem then adds a second, stricter layer on top: even a correctly signed 2-of-2 spend produces no valid Tandem state unless the whole transaction matches an exact template.

An unmatched commitment beside a matched pair On the left, a commitment carrying only side A sits inert: the carrier output is never spent and object state does not change. On the right, side A and side B are both present, the carrier is consumed, and the object advances to the next state sequence. UNMATCHED SIDE A signature present SIDE B absent Carrier not spent no transaction, no event, no state delta Object stays at sequence n the half-record is inert, not pending MATCHED PAIR SIDE A signature present SIDE B signature present Carrier consumed one marker, one exact operation shape Object advances to sequence n+1 valid event, class VALID_OPERATION, reason VALID
The whole protocol in one picture. There is no partially valid Tandem record and no queue of half-signed commitments waiting to complete. Until both halves sign the same exact transaction, the carrier output is simply unspent and the object has not moved.

Side A, the lower-sorted key Side B, the higher-sorted key Inert, no protocol effect

Where pairing appears

Five places a pair must match

Pairing is not one rule. It runs through the entire protocol, and each appearance has its own failure code. This is the quickest way to understand what Tandem actually enforces.

Every pairing requirement, and the stable reason emitted when it fails
PairingRequirementReason on failure
Key pair Two valid, distinct, compressed secp256k1 keys with key0 < key1 by unsigned bytewise order BAD_KEY_ORDER_OR_BINDING (0x0015)
Signature pair Four witness elements: empty, signature for key0, signature for key1, witness script, in that order BAD_SIGNATURE_OR_SIGHASH (0x0016)
Predecessor and successor The marker state_seq is exactly the consumed carrier's sequence plus one BAD_STATE_SEQUENCE (0x001b)
Carrier continuity MARK reproduces the predecessor carrier script byte for byte; ROTATE derives the successor carrier from the new pair BAD_SUCCESSOR (0x001c)
Payout pair CLOSE and REFUND pay key0 and key1 exactly equal, strictly positive amounts BAD_FEE_SPLIT_OR_CHANGE (0x0019)

The last row is worth pausing on. A cooperative ending does not let one side take more than the other. The exit is symmetric by rule, not by agreement, so neither participant has to trust the other's arithmetic at the moment the object ends.

The object

One carrier, five operations, three endings

An active Tandem object is exactly one unspent output, called the carrier: 20,000 satoshis at a native P2WSH address derived from the current key pair. Every operation consumes that carrier and, unless it is terminal, produces the next one.

The five operations plus the markerless recovery path
OperationOpcodeInputsOutputsEffect on the object
INIT0x0012Activates one protocol identifier. Creates no object.
CREATE0x0124Object begins ACTIVE at sequence 0.
MARK0x0223Sequence plus one, chapter count plus one, keys unchanged.
ROTATE0x0334Sequence plus one, keys replaced, chapter count unchanged.
CLOSE0x0413Sequence plus one, status CLOSED, no successor.
REFUNDno marker12Sequence unchanged, status REFUNDED, no successor.

There is also a fourth outcome nobody chooses. If a confirmed transaction consumes an active carrier but fails to validate as one of these operations, the object terminates as EXITED_NONCANONICAL. The spend cannot be ignored, because the output it depended on no longer exists. Tandem never combines, splits, or forks an object.

No market exists for Tandem.

The Bitcoin Universe capability snapshot records 38 protocols, 29 of which have a marketplace entry. Tandem is not among the 38. No Universe product implements a buy, sell, list, or transfer path for a Tandem object, and this repository does not describe one. Tandem defines shared control and a history, not a tradable asset.

Why you can check this yourself

Two implementations, two languages, one answer

A deterministic protocol is only as trustworthy as your ability to disagree with its author. Tandem is implemented twice, independently, in two different languages, and the two implementations share nothing but frozen bytes.

PIPELINE A TypeScript indexer

bitcoinuniverseio/index-tandem resolves Bitcoin data, classifies transactions, and serves object state over HTTP.

PIPELINE B Rust verifier

bitcoinuniverseio/tandem-verifier-rs reimplements the parser, reducer, and roots in Rust and refuses to import pipeline A at all.

The two pipelines never read each other's output. They agree, or fail to agree, only by publishing signed tuples for the same block height and comparing them. That comparison is the real trust property, and the verifier page explains exactly what it does and does not prove.

Where to go next

The rest of the dossier