Contract Operations

State Transitions and their mechanics

The approach followed in this paragraph is the same as that developed in the TxO2 Client-side Validation chapter using our beloved cryptographic characters Alice and Bob.

This time the explanation contains an important difference: Bob is not simply validating the client-side validated data that Alice shows him. He is actually asking Alice to add some additional data that will give Bob some degree of ownership over the contract expressed as a hidden reference to one of his Bitcoin UTXOs. Let's see how the process works in practice for a State Transition (one of the fundamental Contract Operations):

  1. Alice has a stash of client-side validated data, which references a Bitcoin UTXO owned by her. This means that in her client-side validated data there is a seal definition that points to one of her UTXOs.

At the beginning of the State Transition, Alice possesses a certain stash and a UTXO. The idea behind the operation is that she will pass some digital rights in her possession to Bob.
  1. Bob, in turn, also has unspent UTXOs. These UTXOs are completely unrelated to Alice's, which means that there is no direct spending event that creates a link between them. If Bob doesn't possess any UTXO it is also possible to spend towards him the witness transaction output containing the commitment to the client-side data and implicitly associate the ownership of the contract to him.

Bob also owns some UTXOs. Moreover, they are unrelated to Alice's. This UTXO is an important, yet not mandatory, requirement to complete the State Transition. In case Bob doesn't possess any UTXO, it's also possible to spend the witness transaction towards him implicitly associating the new ownership to this new output.
  1. Bob, through some informational data, encoded in an invoice, instructs Alice to create a New state that follows the rules of the contract and which embeds a new seal definition pointing to one of his UTXOs in a concealed form (more on that later). In this way, Alice assigns Bob some ownership of the new state: for example, ownership of a certain amount of tokens.

Bob shares with Alice the necessary data to build the State Transition that assigns him some new state.
  1. After that, Alice, using some PSBT wallet tool, prepares a transaction that spends the UTXO that was indicated by the previous seal definition (the very same one that granted her ownership of some elements of the contracts). In this transaction, which is a witness transaction, Alice embeds in one output a commitment to the new state data that uses Opret or Tapret rules depending on the chosen method. As explained earlier, Opret or Tapret commitments are derived from an MPC tree which may collect more than one contract's state transition.

  2. Before transmitting the transaction thus prepared, Alice passes to Bob a data packet called Consignment which contains the organized stash of client-side data already in possession of Alice in addition to the new state. Bob, at this point, using RGB consensus rules:

    • Validates every RGB state transition in the Consignment, including the one creating some New State assigned to his own UTXO.

    • Verifies that every RGB state transition is committed to in a valid witness transaction, ensuring legitimacy and uniqueness of the whole history from Genesis to the new state.

  3. After checking the correctness of the Consignment, Bob may optionally give Alice a "go-ahead" signal (e.g., by GPG signing the consignment). Alice, even without Bob's clearance, can now broadcast this last witness transaction, containing the New State. Once confirmed, such a witness transaction represents the conclusion of the State Transition from Alice to Bob.

For the detailed process of a contract transfer with the RGB stack, see the related section.

The new state points to Bob's UTXO by assigning him the digital property once in Alice's possession. The new state is committed in the witness transaction that spends the UTXO, which in turn proves Alice's ownership over the digital property that is passed over to Bob. The spending of the UTXO by Alice marks the completion of the State Transition embedding the same level of anti double-spending security as in Bitcoin.

It's useful to see the full details of a DAG of two RGB contract operations - (Genesis + a State Transition) - both from the RGB client-side components, which will be covered in the next few paragraphs, and from the connection points to the Bitcoin Blockchain which embeds the seal definition and the witness transaction.

A representation of RGB Layer (red) and Bitcoin Commitment Layer (orange) and their respective connections during contract operations. The diagram shows the combination of two contract operations: a Genesis, constructing a Seal Definition, and a State Transition which closes the seal previously defined in the Genesis and defines a new seal (new ownership) within another Bitcoin UTXO. The State Transition Bundle is meant to collect more than one State Transition in case multiple seals are closed in the same witness transaction.

Just to give an introduction to the context of the above diagram, let us introduce terminology that will be discussed later in greater technical detail:

  • The Assignment construct, which is pointed at Alice (in this example by the Genesis), and later used by Alice and pointed at Bob, is responsible for two things:

    • The Seal Definition which points to a specific UTXO (to Alice's first, by the Genesis created by a contract issuer, and later to Bob's by Alice herself).

    • The association of the Seal Definition to specific sets of data called Owned States which, depending on the properties of the contract, can be chosen from several types. To give a simple context example, the amount of tokens transferred is a common kind of Owned State.

  • Global State, on the other hand, reflects general and public properties of a contract that are not meant to be owned, such as the total issued supply for a inflatable fungible asset.

As mentioned earlier, a State Transition represents the main form within Contract Operations (in addition to Genesis). State Transitions refer to one or more previously defined state(s) - in Genesis or another State Transition - and update them to a New State.

A detailed view of a State Transition bundle, where two seal belonging to the same contract are closed by the same witness transaction. The diagram separates the RGB specific part from the Bitcoin Commitment Layer part, referencing the related libraries.

As an interesting scalability feature of RGB, multiple State Transitions can be aggregated in a Transition Bundle, so that each bundling operation fits one and only one contract leaf in the MPC tree:

  • A Transition Bundle collects all transitions that refer to a given contract. State Transition details may be selectively revealed to different recipients, while the input map structure we will describe later ensures that allocations can be spent only once.

  • The Transition Bundle is hashed to produce its BundleId, which is included in a leaf of the MPC Tree at a position that is determined by its contract ID.

  • When all bundles are included in the tree, the empty leaves are filled with random data and its merkle root is computed. The MPC commitment, composed by the merkle root and parameters used in the tree construction, is finally included into a Tapret or Opret output thanks to DBC, so that the bitcoin transaction unequivocally commits to a set of RGB state transitions.

  • The Anchor represents the connection point between the Bitcoin Blockchain and the RGB client-side validation structure.

In the following paragraphs, we will delve into all the elements and processes involved in the State Transition operation. All topics discussed from now on belong to RGB Consensus, which is encoded in the RGB Core Library.

Transition Bundle

A transition bundle is essentially the collection of all state transitions in a given witness transaction that operate on a certain contract. In the simplest case, such as the one shown above between Alice and Bob, a Transition Bundle consists of a single state transition.

However, RGB natively supports batching operations, so that one or more payers can send assets to one or more payees and multiple transition types and state types are involved (e.g. atomically sending tokens and inflation rights). In these cases, all the operations involving a certain contract would belong to the same position in the MPC tree, so they need to be deterministically bundled in order to fit in a single MPC leaf. The corresponding witness transaction then needs to close all the seals that are spent by each state transition.

A Transition Bundle contains:

  • input_map, which maps all the Assignments being spent to the State Transition spending each of them; it contains all the information that needs to be committed onchain

  • known_transitions, a subset of all transitions in the bundle whose details are explicitly provided; the remaining ones are said to be concealed

TransitionBundle {
    input_map: Map<Opout, OpId>,
    known_transitions: Vec<KnownTransition>,
}

Assignments are identified by the Opout structure, which contains:

  • the Identifier of the Operation that created this Assignment

  • assignment Type, distinguishing for instance token ownership from issuance Rights

  • assignment Number, the index of this assignment within the previous operation, akin to bitcoin's vout

Opout {
    op: OpId,
    ty: AssignmentType,
    no: u16,
}

BundleId

From a more technical angle, the BundleId to be inserted in the leaf of the MPC is obtained from a tagged hash of the strict serialization of the input_map field of the bundle in the following way:

BundleId = SHA-256( SHA-256(bundle_tag) || SHA-256(bundle_tag) || input_map )

Where:

  • bundle_tag = urn:lnp-bp:rgb:bundle#2024-02-03

The input map gets serialized in the following way:

input_map =

     N                    Opout_1                       OpId_1                     Opout_N                       OpId_N
|__________||_____________________________________||____________| ... |_____________________________________||____________|
 16-bit LE   32-byte hash + 16-bit LE + 16-bit LE   32-byte hash       32-byte hash + 16-bit LE + 16-bit LE   32-byte hash
|__________||___________________________________________________| ... |___________________________________________________|
   MapSize                       MapElement_1                                              MapElement_N

Where:

  • N is the total number of opouts spent by some transition in the current bundle.

  • Opout_i is the i-th spent Assignment, which contains:

    • 32-byte previous operation ID

    • 16-bit assignment type, e.g. 4000 for nia assets

    • 16-bit assignment number

  • OpId_i is the Operation Identifier of the State Transition which spends the i-th Assignment

  • Opouts are sorted lexicographically to obtain a deterministic BundleId

Note: A given OpId may appear multiple times if a transition spends multiple assignments, but the opposite is not true. An Opout can only be spent by a single State Transition, which guarantees the absence of double spends if we consider that the corresponding seal is closed by the witness transaction. As a consequence, some State Transition may be omitted (concealed) from the Bundle for privacy reasons, while their OpId inside the input map ensures that no other (possibly concealed) transition can spend the same Opout(s).

State Generation and Active State

State transitions, just covered in the previous sections, allow the transfer of ownership of certain state properties from one party to another. However, state transitions are only one of the Contract Operations allowed in RGB. The other one, which allows to generate new state at the issuance of a contract, is called Genesis.

The following figure shows the three components of contract operations along with their position in the RGB contract DAG, linked to their respective anchors in the Bitcoin Blockchain. State Transitions are represented by the red blocks.

It is important to note that the main difference between ordinary State Transitions and Genesis lies in the lack of the closing part of the seal. Hence Genesis is only committed into the blockchain history when a State Transition closes one of the seals defined by it.

Another obvious, but crucial, aspect to keep in mind is that the Active State(s) are the last state(s) at the leaves of the DAG of contract operations that reference themselves in the order committed into the Bitcoin Blockchain, starting from the Genesis. All other states associated with spent UTXOs are no longer valid but are critical to the validation process.

Genesis

Genesis represents the initial data block of each RGB contract. It is constructed by a contract issuer and any state transitions must be connected to it through the DAG of the contract operations. In Genesis, according to the rules defined in the Schema, are defined several properties affecting deeply the contract states, both of owned and global form.

To give an example, in the case of a contract defining the creation of a token, the following data are likely to be inscribed in Genesis:

  • The number of tokens issued and their owner(s) (the owner(s) of the UTXO referred to in the seal definition's genesis).

  • The maximum number of tokens to be issued in total.

  • The possibility of inflation and the designed party that possesses this right.

As a natural implication, Genesis does not refer to any previous state transition, nor does it close any previously defined seal. As mentioned above, to be effectively validated in the history of the chain, a Genesis must be referenced by a first state transition (e.g. an auto-spend to the issuer or a first round of distribution), which finalizes the "first ownership" of the contract through a commitment to the Bitcoin Blockchain.


Last updated