Transition bundles
Transition bundles are part of v0.11 consensus. v0.12 removed them, as described at the end of this page. See Two RGB lines.
A transition bundle is the set of all state transitions of one contract that are committed in the same witness transaction. It is not a way to put several contracts together: each contract in a witness transaction has its own bundle.
Why bundles exist​
One Bitcoin transaction can close seals of several contracts and several transitions of the same contract. For example, a payer might merge two allocations, or send tokens and inflation rights together. The witness transaction carries a single commitment, so RGB arranges the data in two layers:
- Per contract: all transitions of contract C in this transaction form one
TransitionBundle. ItsBundleIdgoes into the MPC tree. - Across contracts: the MPC (multi-protocol commitment) tree has one leaf per contract, at a position set by the contract ID. Empty leaves are filled with random data.
- On chain: the MPC root goes into one tapret or opret output (DBC).
So batching many contracts into one transaction is done by the MPC tree, not by the bundle. Source: State Transitions in the official docs, and the glossary entry "Transition Bundle".
The structure​
From rgb-consensus 0.11.1 src/operation/bundle.rs:
pub struct TransitionBundle {
pub input_map: NonEmptyOrdMap<Opout, OpId, U16MAX>,
pub known_transitions: NonEmptyVec<KnownTransition, U16MAX>,
}
pub struct KnownTransition {
pub opid: OpId,
pub transition: Transition,
}
input_mapmaps every assignment being spent (anOpout: operation ID, assignment type, index) to the transition that spends it. Only this map goes into the commitment (CommitEncodecommits toinput_map), and because a map key can appear only once, a single assignment can't be spent by two transitions in the same bundle.known_transitionsholds the transitions whose contents are revealed. A consignment for one recipient can leave out (conceal) transitions that don't concern them. Their opids are still ininput_map.- Both collections are limited to 65,535 entries (
U16MAX).
The bundle has no anchor or witness field. The anchor (MPC proof plus DBC proof) and the witness transaction are carried next to the bundle in the consignment.
In practice​
You don't build bundles by hand. rgb transfer in rgb-cmd and send in rgb-lib create them:
- rgb-cmd 0.11.1:
rgb transfer <INVOICE> <CONSIGNMENT> [PSBT]builds the transitions, the bundle, the MPC commitment and the PSBT (CLI reference). - rgb-lib 0.3.0-beta.7:
send(orsend_begin/send_end) takes a map of asset ID → recipients. All recipients share one Bitcoin transaction, and rgb-lib writes one consignment per asset (Transferring assets).
When a transaction spends a UTXO that holds state of several contracts, the wallet must also move the state of those other contracts, usually to change. Otherwise that state is lost. Both tools handle this.
A Bitcoin wallet that doesn't know about RGB can spend a UTXO that holds allocations of several contracts. It creates no bundles for them, so all of that state is destroyed. Keep RGB UTXOs in a wallet that only RGB software controls.
RGB v0.12​
v0.12 has no transition bundles in consensus: the rgb-core 0.12 changelog lists "Remove transition bundles" and "Remove anchors". The wallet layer still groups the operations of one witness transaction in a PrefabBundle, a set of Prefab { closes, defines, operation } (rgb-std 0.12.0-rc.3 src/popls/bp.rs). rgb exec writes one, and rgb complete adds it to the stash after the PSBT is committed. rgb pay does both internally. See CLI reference (v0.12).