# RGB Protocol Documentation

RGB is a protocol developed in order to enforce digital rights in form of contracts and assets in a scalable and private manner leveraging Bitcoin consensus rules and operations.

This guide targets the broader technical audience willing to understand in depth the RGB protocol, from its theoretical foundations rooted in [Client-side Validation](/annexes/glossary#client-side-validation) and [Single-use Seals](/annexes/glossary#single-use-seal) to the more core features of [State Transitions](/annexes/glossary#state-transition) and Contract Structure. The relevant terms and concepts will be introduced step by step and they will be referenced to external material in case more detailed study by non computer science audience is needed.

{% hint style="info" %}
RGB Protocol on Bitcoin — not to be confused with:

* The RGB color model (Red, Green, Blue — unrelated)
* RGB v0.12 (unfinished proposal do rewrite the protocol, promoted by the owner of the RGB-WG organization)
* RGB++ (a separate protocol on the Nervos/CKB blockchain — different team, different architecture)

For general information and education visit [rgb.info](https://rgb.info).
{% endhint %}

## Table of Contents

### Distributed Computing Concepts

* [Paradigms of Distributed Computing](/distributed-computing-concepts/paradigms-of-distributed-computing)
* [Client-side Validation](/distributed-computing-concepts/client-side-validation)
* [Single-use Seals and Proof of Publication](/distributed-computing-concepts/single-use-seals)

### Commitment Layer

* [Commitment Schemes within Bitcoin and RGB](/commitment-layer/commitment-schemes)
* [Deterministic Bitcoin Commitments - DBC](/commitment-layer/deterministic-bitcoin-commitments-dbc)
  * [Opret](/commitment-layer/deterministic-bitcoin-commitments-dbc/opret)
  * [Tapret](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret)
* [Multi Protocol Commitments - MPC](/commitment-layer/multi-protocol-commitments-mpc)
* [Anchors](/commitment-layer/anchors)

### RGB State and Operations

* [Introduction to Smart Contracts and their States](/rgb-state-and-operations/intro-smart-contract-states)
* [Contract Operations](/rgb-state-and-operations/state-transitions)
* [Components of a Contract Operation](/rgb-state-and-operations/components-of-a-contract-operation)
* [Features of RGB State](/rgb-state-and-operations/features-of-rgb-state)

### RGB Contract Implementation

* [Schema](/rgb-contract-implementation/schema)
  * [Supported Schemas](/rgb-contract-implementation/schema/supported-schemas)
  * [Schema example: Non-Inflatable Assets](/rgb-contract-implementation/schema/non-inflatable-fungible-asset-schema)

### RGB over Lightning Network

* [Lightning Network compatibility](/rgb-over-lightning-network/lightning-network-compatibility)

### Annexes

* [Glossary](/annexes/glossary)
* [Contract Transfers](/annexes/contract-transfers)
* [Invoices](/annexes/invoices)
* [Commitments](/annexes/commitments)
* [RGB Library Map](/annexes/rgb-library-map)
* [Bitcoin Single-use Seals](/annexes/single-use-seals-bitcoin)

## Credits

The production of this documentation has been sponsored by [Bitfinex](https://www.bitfinex.com/) and the material provided is mostly based on a 3-day full-immersion seminar on RGB Protocol held by [Maxim Orlovsky](https://twitter.com/dr_orlovsky) at the Tuscany Lightning Bootcamp in October 2023.

Videos: <https://planb.academy/courses/3ce1d37c-05ba-4f54-aa15-7586d37b2bb7>

***


# Paradigms of Distributed Computing

Before divining into the technical details of the RGB, the introduction to the fundamental concepts of the technology and the study of the base terminology represent an essential step towards a thorough understanding of the subject.

Indeed RGB it's a combination of several pieces of the Distributed Computing Domain, in particular:

* [Commitment](/annexes/glossary#commitment) scheme with cryptographic hash functions.
* [Client-side Validation](/annexes/glossary#client-side-validation).
* [Single-use Seals](/annexes/glossary#single-use-seal).

The combination of these topics is the underlying substrate that makes RGB operational.

RGB locates itself as a new additional piece of the vast world of *Distributed Computing*.

**Distributed computing**, is a branch of Computer Science that studies the protocol systems able to exchange and compute data information between a network of computer nodes: the set of computer nodes and the underlying protocol rules that allow the computation of these data are the constituents of a **Distributed System**.

The **nodes** composing the network **are able to independently verify and validate some set of data** and they can construct, depending on the protocol, complete or partial snapshots of information elaborated by the network: these are called the **states** of the distributed system and essentially represent the expression of properties and the underlying agreement over those properties that are established during network operations.

The most important property of a distributed system is represented by the **Chronological Ordering** of the operations and the related data timestamp and thus the **ordered sequence of state changes** that take place inside the system. In fact when we talk about **Consensus**, we are talking about:

1. **Recognizing the validity of the state changes** by the nodes according to the protocol rules.
2. **Establishing consensus on the order of the state changes** so that every node knows which operation precedes the other and the state cannot be reversed once it has changed: the so-called **anti double-spend property**.

The achievement of a *resilient and reliable* chronological ordering for distributed systems, which embeds important properties such as permissiveness and censorship resistance, was reached by Satoshi Nakamoto with the invention of Bitcoin, using the blockchain data structure and a **Proof-of-Work (PoW)** consensus which is able to entrust different validating participants to the system according to their computational power. Indeed Bitcoin can be considered the first working example of a permissionless **Distributed Consensus System**.

We will discuss various kinds of **Distributed Consensus Systems** which have some degree of hierarchy and interrelated properties between them. They are differentiated on **how they determine and enforce the most updated state of the system**:

* **Blockchain + PoW Mechanism**. The sequence of **state transitions** is public and auditable and is organized in **transactions** included in ordered blocks which are added one upon the other. The system's security lies in the amount of work required to produce an alternative chain which reverts the actual greater-work chain, which is considered the valid chain. For instance, **Bitcoin** is based on this technological stack.
* **State Channels**. Is a system constructed between 2 (or more) parties and which **depend hierarchically** on the blockchain layer. **The final state is represented by the last transaction out of sequence of ordered invalidating transactions, signed and agreed by the parties \_off-chain**\_. The final state can be enforced by each parties by publishing that last valid transaction on the layer 1. The most known application of payment channels, a simplified form of state channels, is the [Lightning Network](/annexes/glossary#lightning-network).
* **Client Side Validated Data - Stash**. Is a system that c**an be implemented both on top of blockchain and state channels** and it is based on a certain amount of data whose validity, computation tasks and uplocatesdate is entrusted to a limited number of nodes. Unlike layer 1, the data to be validated by each client node represent a **defined subset of the entirety of all state transitions of the client-side protocol, and not every transition happened within it**. This validated subset of data in possession of a client node is what is called **Stash**. Basically, the client needs to validate the whole history of the state transitions that occurred from the first to the last [transition](/annexes/glossary#state-transition) and which relate to some digital properties exchanged among the counterparties involved. Seen as a whole, the validation mechanism of the shard that produces the stash is called **Client-side Validation** and is at the base of all **RGB** operations.

<figure><img src="/files/kobvF8nRgECCeQyVZqvb" alt=""><figcaption><p><strong>The 3 set of Distributed System - Blockchain (Layer 1) is self-sustaining while the other 2 rely on Layer 1 for operating. In turn, Stashes can operate on top of both Blockchain and State Channels.</strong></p></figcaption></figure>

In order to precisely frame the applications of each Distributed Consensus System and their underlying data structure it's important to understand the limitations that affect each one of these technology. This condition is expressed in form of a **Trilemma** which is connected to an important theoretical result of Distributed Computing, known as [CAP Theorem](https://en.wikipedia.org/wiki/CAP_theorem). which states that:

> Any distributed system can provide simultaneously only two of the following three guarantees:
>
> * Consistency - Every node in the system agree on the current global state.
> * Availability - Every request to the system receives a response.
> * Partition Tolerance - The system continues to operate correctly despite a network partition, e.g. failures or delays between nodes.

<figure><img src="/files/1V99lI3j1sR2zYz3SKTY" alt=""><figcaption><p><strong>Application of CAP Theorem to Distributed Consensus System - Each Distributed Consensus System can fit 2 - and only 2 - out of the 3 properties.</strong></p></figcaption></figure>

Seen from a more consensus-focused point of view, the properties of the theorem can be reformulated in the following way:

* **Consistency** ==> Integrity
* **Availability** ==> Decentralization
* **Partition Tolerance** ==> Scalability and Confidentiality

<figure><img src="/files/A8i1uEh9xIdoT7Vg8mEN" alt=""><figcaption><p><strong>A more in-depth view of the inherent degree of application of the Trilemma to Distributed Consensus System.</strong></p></figcaption></figure>

In synthesis:

* **Blockchains** preserve Integrity and Decentralization but **lack Scalability** and Confidentiality as each node needs to replicate *publicly and in full* every state transition.
* **State Channels** preserve Decentralization and Scalability but **don't preserve Integrity** as the state can be changed or updated asynchronously by the counterparties.
* **Stashes of client-side validated data** are Scalable and maintain Integrity however, they **are not replicated** by the vast majority of nodes of the network **lacking Availability**. For this reason, these data are not fully recoverable in a completely decentralized way and some form of centralized backup is needed to recover them in case of loss.

An important feature to take into account is the different ways through which State Channel and Client-Side validation architectures update the state of the data:

* Channel state must be **synchronous** between the counterparts.
* Client-side validated state updates can be **asynchronous**.

Naturally, if the client-side validated data are embedded in the state channels, the state update will be ultimately based on an asynchronous process.

<figure><img src="/files/VaSdI4dW9wqyFy6ScXPd" alt=""><figcaption><p><strong>Blockchain is the base layer over which multiple-interacting layers can be constructed</strong></p></figcaption></figure>

In addition to the three layers just described, a fourth layer of Bitcoin Finance (#BiFi) which leverages both state channels and blockchain can complete the whole ecosystem. The general picture and the deep interconnections of all the layers, with the blockchain layer at the base, allow to achieve all the properties of the CAP theorem in a composite way.

In the next section, we will delve into Client-side Validation and its features.

***


# Client-side Validation

The goal of every validation process in a distributed system is the **ability to assess the validity and chronological ordering of states**, hence to verify the correctness of the protocol rules of the state transitions that have occurred.

<figure><img src="/files/8cacGrn72geOtAHO4rpK" alt=""><figcaption><p><strong>Consensus system allows for the tracking of the state evolution of some properties</strong></p></figcaption></figure>

In Bitcoin Blockchain, for instance, this process is meant to verify the correctness of the changes in the [UTXO set](https://en.wikipedia.org/wiki/Unspent_transaction_output) determined by the transactions collected into the sequence of ordered blocks. Thus, every block represents a **state update**.

<figure><img src="/files/TywijEKaNCS9nKMLEBwa" alt=""><figcaption><p><strong>In Bitcoin the System State is represented by the UTXO Set, reflecting the ownership of bitcoins.</strong></p></figcaption></figure>

The main drawback of Layer 1's validation process is that **each node has to validate each transaction from everybody and store the related data** once block inclusion takes place. This architecture leads to two main issues:

* **Scalability**: the size limit of the blocks vs. the demand of blockspace per unit time shared by all willing participants limits the transaction throughput (i.e. a maximum of 1 MB on \~10 minutes on average on bitcoin, taking into account [witness discount](https://en.bitcoin.it/wiki/Segregated_Witness)).
* **Privacy**: details of each transaction are broadcasted and stored in public form (in particular: the amounts transacted and the receiving addresses, although pseudonyms).

<figure><img src="/files/R91AMSaZjnphWYDKD8NZ" alt=""><figcaption><p><strong>In Public Blockchains everyone needs to validate all the information leading to privacy and scalability issues.</strong></p></figcaption></figure>

However, from the point of view of the recipient of a transaction, the only aspects that matter are:

* The last state transition, that is represented by a transaction addressed to him.
* The chronological sequence of transactions (and thus state transitions) leading up to the last state transition.

Basically, what is relevant to the recipient is the [Directed Acyclic Graph](/annexes/glossary#directed-acyclic-graph-dag) which connects the history of the state transitions from the [Genesis](/annexes/glossary#genesis) to the last state addressed to him (a [Shard](/annexes/glossary#shard) of the whole data).

<figure><img src="/files/EAKZwXFgzXyEfSAgpzlA" alt=""><figcaption><p><strong>The transaction graph of Public Blockchains cannot be sharded due to internal consistency.</strong></p></figcaption></figure>

For this reason, the **logic of validation can be reversed** in the following terms:

* Each part validates its **own part of the history** and thus the digital properties that matter to him.
* A compact reference of the **validated state transition is committed in Layer 1** to be timestamped. This construction constitutes a [Proof-of-Publication](https://petertodd.org/2017/scalable-single-use-seal-asset-transfer) and acts as an **anti double-spending measure**.

<figure><img src="/files/pF1gAKuunvjxbH1hEwo7" alt=""><figcaption><p><br><strong>Layer 1's blocks are kept public, but client-side validated state transitions are aggregated and committed through suitable merkelization in Layer 1's transactions.</strong></p></figcaption></figure>

**Client-side Validation** ensures that the following properties are met:

* **Scalability**: since the commitment of the verified state, which must be stored by all, has, at least, a small footprint (order of tens of bytes), or, in [some commitment scheme](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret), no additional footprint in respect to an ordinary transaction.
* **Privacy**: using a [one-way cryptographic hash function](https://en.wikipedia.org/wiki/Cryptographic_hash_function) (such as [SHA-256](https://en.wikipedia.org/wiki/SHA-2)), the original data (the pre-image) that produced the commitment cannot be reconstructed and it is kept private by the parties.

<figure><img src="/files/9t6mwMdDOEn53AC5kM10" alt=""><figcaption><p><strong>Several shards can be aggregated in a single Layer 1 transaction. The Anchor structure establish a link between the client-side data of the contract and the single-use seal.</strong></p></figcaption></figure>

The commitment structure used in Client-Side Validation (as in the RGB protocol, which we will cover in detail [later](/commitment-layer/commitment-schemes)) allows for important additional scalability features:

* Aggregate state transitions of different contracts (e.g., two different contracts related to 2 different digital assets committed in a single Bitcoin transaction).
* Bundle more than one state transition of the same asset in the same client-side operation.

[Anchor](/commitment-layer/anchors) structures provide the deterministic link between the [single-use seal](/distributed-computing-concepts/single-use-seals) and the client-side data that represent the message to which the [single-use seal is closed over](/distributed-computing-concepts/single-use-seals#seal-closing).

To guarantee the efficacy of the commitment scheme and precise chronological ordering derived from Layer 1, the use of a new cryptographic primitive needs to be introduced: the **Single-use Seal**.

***


# Single-use Seals and Proof of Publication

Single-use Seals are cryptographic primitives [proposed](https://petertodd.org/2016/commitments-and-single-use-seals) by Peter Todd in \~2016. They are a kind of **cryptographic commitment** that resembles the application of a physical seal to a container. They can be used to prove a sequence of events to a party, thereby limiting the risk that such a sequence may be altered after it has been established. This implies that such commitment schemes are a more sophisticated form of both `simple commitments` (i.e. digest/hash) and `timestamping`.

<figure><img src="/files/5x56Ycy8JTLZYEyNjLOX" alt=""><figcaption><p><strong>Physical single-use seals: once closed their protected content cannot be altered</strong></p></figcaption></figure>

To work properly, Single-use Seals require a **Proof-of-Publication Medium**: it may be a medium with global consensus (such as blockchains), not necessarily decentralized, which has the ability to be difficult to forge or replicate once issued and made public. A **newspaper** represents a widespread example of this concept.

The **Proof-of-Publication Medium** will be used:

* To prove that *every* member `p` in an audience `P` has received a certain message `m`.
* To prove that the message `m` has not been published.
* To prove that some member `q` is in the audience `P`.

With these properties, we can give a more formal definition:

> *Single-Use-Seal is a formal promise to commit to a (yet) unknown message in the future, once and only once, such that the fact of commitment is demonstrably known to all members of a certain audience.*

With this definition and the general properties above, we can compare the properties of the various cryptographic primitives along with Single-use Seals:

| Property                                                             | Simple commitment (digest/hash) | Timestamp    | Single-Use-Seals |
| -------------------------------------------------------------------- | ------------------------------- | ------------ | ---------------- |
| Commitment publication does not reveal the message                   | Yes                             | Yes          | Yes              |
| Proof of the commitment time / message existence before certain date | Not Possible                    | Possible     | Possible         |
| Prove that no alternative commitment can exist                       | Not Possible                    | Not Possible | Possible         |

So how can we practically construct a disposable seal and what operations have to be used? In general, the principles of operation include 3 steps:

* **Seal Definition**.
* **Seal Closing**.
* **Seal Verification**.

For the following operation examples, we will use the well-known computer science characters, Alice and Bob.

### **Seal Definition**

In Seal Definition, Alice promises to Bob (either in private or in public) to create some **message** (in practice a hash of some data):

* At a well-defined point in time and space.
* Using an agreed publication medium.

### **Seal Closing**

When Alice publishes the **message** following all the rules stated in the Seal definition, in addition, she produces also a **witness**, which is the proof that the seal has indeed been closed.

<figure><img src="/files/Q96IE9r1caN35DFQOoFi" alt=""><figcaption><p><strong>By closing a message with a single-use seal, such message cannot be altered. In it's digital form, inscribed in Layer 1, the seal cannot be opened any more.</strong></p></figcaption></figure>

### **Seal Verification**

**Once closed the seal, being "single-use", cannot be opened nor closed again.** The only thing Bob can do is to check whether the seal has actually been closed around the message commitment, using as inputs: the seal, the witness, and the message (which is a commitment to some data).

In Computer Science Language the whole procedure can be summed up as follows:

```
seal <- Define()                         # Done by Alice, accepted by Bob.

witness <- Close(seal, message)          # Close a seal over a message, done by Alice.

bool <- Verify(seal, witness, message)   # Verify that the seal was closed, done by Bob.
```

The combination of Single-Use-Seals and Client-Side-Validation enables a distributed system that does not require global consensus (i.e. a blockchain) to store all the data that matters to some counterparts, providing a high level of scalability and privacy. However, this is not enough to make the system work. Because the definition of a single-use seal is done on the client side and does not need to be included in the global consensus medium, **a party can’t prove that the definition of the seal ever took place** even if one is a member of the audience observing the publication medium.

We therefore need a **“chain” of Single-Use-Seals**, where **the closure of the previous seal incorporates the definition of subsequent seal(s): this is what RGB does together with Bitcoin**:

* Messages represent the commitment to client-side validated data.
* Seal definitions are bitcoin UTXO.
* The commitment is a hash entered within a Bitcoin transaction.
* The seal closure can be a UTXO that is spent or an address to which a transaction credits some bitcoins.
* The chain of connected transaction spends represents the Proof-of-Publication.

In the next chapters, we will explore in detail how RGB implements the concept of Single-Use-Seal by storing the commitments of its operation in the Bitcoin blockchain.

***


# Commitment Schemes within Bitcoin and RGB

In this chapter we will explore the application of Client-side Validation and [Single-use Seal](/annexes/glossary#single-use-seal) to Bitcoin Blockchain, introducing the main architectural features behind **RGB protocol related to the commitment layer (layer 1)**.

As mentioned in the [previous chapter](/distributed-computing-concepts/paradigms-of-distributed-computing), these cryptographic operations can be applied in general to different blockchains and also to different publication media. However, the outstanding properties of Bitcoin consensus algorithm, particularly those related to decentralization, censorship resistance, and permissionlessness, make it the ideal technology stack for the development of advanced programmability features, such as those required by digital bearer rights and smart contracts.

From the previous section, we recall that the creation of Single-use Seals is subject to two basic operations: [Seal Definition](/distributed-computing-concepts/single-use-seals#seal-definition) and [Seal Closing](/distributed-computing-concepts/single-use-seals#seal-closing). We will now explore how these two operations are implemented **using Bitcoin Transactions as a publication medium** for the RGB protocol. A a more generic overview on single-use seals constructions on the bitcoin blockchain can be found [here](/annexes/single-use-seals-bitcoin).

### Single-use Seals in RGB

RGB seals are represented by bitcoin unspent transaction outputs (UTXO), so that:

* A seal is **defined** by some **state** that points to a UTXO that identifies its owner
* A seal is **closed** around a **message** when a transaction spends the UTXO and commits to a message

These two operations are then chained together by including a seal definition in the message around which the previous seal is closed, so that the [witness transaction](/annexes/glossary#witness-transaction):

* spends the UTXO on which a seal was defined, thus closing the seal
* has an output that contains a commitment to a new seal definition

### RGB Client-side Validation

In the next paragraphs, we will focus on client-side validation combined with the above construction of a single-use seal, showing them step by step trough the usual cryptographic characters: Alice, who deals with a seal operation, and Bob as an observer.

1. First of all, Alice has a [UTXO](/annexes/glossary#utxo) **that is linked to some client-side validated data** known only by her.

<figure><img src="/files/98pi4jhLNoDSNmBbfrk8" alt=""><figcaption><p><strong>A seal definition is applied to a specific Bitcoin UTXO.</strong></p></figcaption></figure>

2. Alice informs Bob that the spending of these UTXO represents a sign that some seal was closed.

<figure><img src="/files/w9kUsGi9LDjjEIGKvWeZ" alt=""><figcaption><p><strong>The UTXO is associated to some meaning agreed between Alice and Bob.</strong></p></figcaption></figure>

3. Once Alice spends her UTXO, only Bob knows that this event has some additional meaning and consequences, even though everyone (i.e. the Bitcoin Blockchain audience) can see it.

<figure><img src="/files/qFhSiIEDnkU3pxDBMPU2" alt=""><figcaption><p><strong>The spending event of the UTXO triggers some meaningful consequences for the parties involved.</strong></p></figcaption></figure>

4. In fact, the UTXO spent by Alice through the [witness transaction](/annexes/glossary#witness-transaction) contains a commitment to a change in the client-side validated data. By passing the original data to Bob, she is able to prove him that it is properly referenced by the commitment that Alice included in the witness transaction. Bob can independently verify that the new seal definition is unequivocally bound to the seal closing, so that no other players can be convinced to accept a different one as valid, effectively **preventing double spend**.

<figure><img src="/files/W5yNK51FGmEX3z4Skze3" alt=""><figcaption><p><strong>Alice can prove to Bob deterministically the uniqueness of the message committed. In addition the message may contain another seal definition extending the chain of commitments.</strong></p></figcaption></figure>

The key point of using the single-use seal in combination with client-side validation is the uniqueness of the spending event and the data committed (i.e., the message) in it, which cannot be changed in the future. The whole operation can be summarized in the following terms.

<figure><img src="/files/8aXaAGbclhVj1iyIG5zg" alt=""><figcaption><p><strong>The UTXO being spent represents the seal closing. A precise kind of transaction output contains the message, which represents a new seal definition.</strong></p></figcaption></figure>

The next important step is to illustrate precisely how the two commitment schemes adopted in RGB protocol, **Opret** and **Tapret**, work and which features they must meet, particularly concerning commitment determinism.

***


# Deterministic Bitcoin Commitments - DBC

For RGB commitment operations, the main requirement for a Bitcoin commitment scheme to be valid is that:

> The witness transaction must provably contain a single commitment.

With this requirement, it is not possible to construct an "alternative history" related to client-side data commitment in the same transaction. Thus, the message around which the single-use seal is closed is unique. To meet the above requirement, regardless of the number of outputs in a transaction, *one and only one output* contains a valid commitment (either Opret or Tapret):

> The only valid output that can contain an RGB message commitment is the first DBC-compatible output, i.e. the first that has either:
>
> 1. an OP\_RETURN spending script; in this case it will encode its Opret commitment there
> 2. a taproot spending script; in this case it will encode its Tapret commitment in the corresponding taproot tree

It is worth observing that a transaction **only contains either a single** `Opret` **OR a single** `Tapret` commitment in the first applicable output. This approach guarantees uniqueness of the seal closing strategy without committing to it at seal creation, allowing to avoid the complexity of transfers involving multiple commitment schemes. This means that, in case a witness transaction contains both a taproot and an OP\_RETURN output, the second one will be ignored by the RGB validation.

***


# Opret

This represents the simplest and most straightforward scheme. The commitment is inserted into the first `OP_RETURN` output of the [witness transaction](/annexes/glossary#witness-transaction) in the following way:

```
34-byte_Opret_Commitment =
 OP_RETURN   OP_PUSHBYTE_32   <mpc::Commitment>
|_________| |______________| |_________________|
  1-byte       1-byte         32 bytes                      
```

`mpc::Commitment` is the 32-byte Tagged hash resulting from the [MPC tree](/commitment-layer/multi-protocol-commitments-mpc#mpc-tagged-hash) which is covered in detail [later](/commitment-layer/multi-protocol-commitments-mpc). Hence an opret commitment will have a total size of 34 bytes.

***


# Tapret

The `Tapret` scheme is a more complex form of deterministic commitment and represents an improvement in terms of chain footprint and privacy of contract operations. The main idea of this application is to hide the commitment within the `Script Path Spend` of a [taproot transaction](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki).

First, before describing how the commitment is actually embedded in a taproot transaction, we will show the exact **form of the commitment which must match exactly a 64-byte string size** [constructed](https://github.com/BP-WG/bp-core/blob/master/dbc/src/tapret/mod.rs#L179-L196) as follows:

```
64-byte_Tapret_Commitment =

 OP_RESERVED ...  ... .. OP_RESERVED   OP_RETURN   OP_PUSHBYTE_33  <mpc::Commitment>  <Nonce>
|___________________________________| |_________| |______________| |_______________|  |______|
 OP_RESERVED x 29 times = 29 bytes      1 byte         1 byte          32 bytes        1 byte
|________________________________________________________________| |_________________________|
        TAPRET_SCRIPT_COMMITMENT_PREFIX = 31 bytes                    MPC commitment + NONCE = 33 bytes
```

Thus the 64-byte `Tapret` commitment is an `Opret` commitment preceded by 29 bytes of the `OP_RESERVED` operator and to which is added a 1-byte `Nonce` whose usefulness will be addressed [later](#nonce-optimization).

In order to preserve highest degree of implementation flexibility, privacy and scalability, **the Tapret scheme is designed to integrate many different cases that occur according to the user's bitcoin spending needs**. Specifically we distinguish the following Tapret scenarios:

* **Single incorporation** of a Tapret commitment into a taproot transaction **without a pre-existing Script Path Spend structure**.
* **Integration** of a Tapret commitment into a taproot transaction **containing a pre-existing Script Path Spend structure**.

We will analyze each of these scenarios in depth in the next paragraphs.

## **Tapret Incorporation without pre-existing Script Path Spend**

In this first scenario, we start with a Taproot Output Key `Q` consisting only of an Internal Key `P` and **no Spending script path**:

```
+---+            +---+   +---+   +---+
| Q |      =     | P | + | m | * | G |
+---+            +---+   +-^-+   +---+
                           |
                    +-------------+
                    | tH_TWEAK(P) |
                    +-------------+
```

* `P` is the Internal Public Key of the *Key Path Spend.*
* `G` is the Generator point of [secp256k1](https://en.bitcoin.it/wiki/Secp256k1) elliptic curve.
* `t = tH_TWEAK(P)` = SHA-256(SHA-256(*TapTweak*) || SHA-256(*TapTweak*) || P) is the tweaking factor derived from the tagged hash representing the commitment to the public key `P`. The construction makes use of [BIP86](https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki#address-derivation) to show that there is no hidden alternative Script Path Spend.

In order to include the Tapret commitment, **the transaction is modified to include a Script Path Spend containing a single script** according to the following scheme:

```
+---+            +---+   +---+   +---+
| Q |      =     | P | + | t | * | G |
+---+            +---+   +-^-+   +---+
                           |
             +----------------------------+
             | tH_TWEAK(P || Script_root) |
             +---------------------^------+
                                   |
         +-------------------------+------------+
         | tH_BRANCH(64-byte_Tapret_Commitment) |
         +--------------------------------------+
```

* `t = tH_TWEAK(P || Script_root)` = SHA-256(SHA-256(*TapTweak*) || SHA-256(*TapTweak*) || P || Script\_root) is the modified tweaking factor.
* `Script_root = tH_BRANCH(`64-byte\_Tapret\_Commitment`)` = SHA256(SHA-256(*TapBranch*) || SHA-256(*TapBranch*) || 64-byte\_Tapret\_Commitment) is the script root of the Script Path Spend.

The proof of inclusion and uniqueness in the Taproot Script Tree is only the internal key `P`.

## **Tapret incorporation in pre-existing Script Path Spend**

To move on to the construction of this more complex case, we show below the structure of a taproot output Key `Q`, which in this example consists of a Spend Key Path with internal key `P` and a 3-script tree in the Spend Script Path.

```
+---+            +---+   +---+   +---+
| Q |      =     | P | + | t | * | G |
+---+            +---+   +-^-+   +---+
                           |
             +----------------------------+
             | tH_TWEAK(P || Script_root) |
             +---------------------^------+
                                   |
                     +-------------+----------+
                     | tH_BRANCH(tHAB || tHC) |
                     +------------^-------^---+
                                  |       |
                        +---------+       +---------+
                        |                           |
           +------------+----------+         +------+-----+
           | tH_BRANCH(tHA || tHB) |         | tH_LEAF(C) |
           +------------^------^---+         +------^-----+
                        |      |                    |
                 +------+      +------+             |
                 |                    |             |
           +-----+------+       +-----+------+      |
           | tH_LEAF(A) |       | tH_LEAF(B) |      |
           +-----^------+       +-----^------+      |
                 |                    |             |
               +-+-+                +-+-+         +-+-+
               | A |                | B |         | C |
               +---+                +---+         +---+
```

Where:

* `tH_LEAF(x)` = SHA-256(SHA-256(*TapLeaf*) || SHA-256(*TapLeaf*) || version\_leaf(x) || size(x) || x) is the standard tagged hash of a script leaf in taproot Script Path Spend.
* `A, B, C` are some Bitcoin scripts of this example taproot script tree.

The RGB Tapret commitment rule imposes the following requirements:

**1) Tapret Commitment is entered as an unspendable script at the 1st level of the Script Tree, shifting all other scripts 1 level below.**

The new Taproot Output Key `Q` including the Tapret commitment is built as follows:

```
+---+            +---+   +---+   +---+
| Q |      =     | P | + | t | * | G |
+---+            +---+   +-^-+   +---+
                           |
                           +--------------------+
                                                |
                                +---------------+------------+
                                | tH_TWEAK(P || Script_root) |
                                +---------------------^------+
                                                      |
                                       +--------------+----------+
                                       | tH_BRANCH(tHABC || tHT) |
                                       +-------------^-------^---+
                                                     |       |
                     +-------------------------------+       +-------+
                     |                                               |
          +----------+-------------+               +-----------------+--------------------+
          | tH_BRANCH(tHAB || tHC) |               | tH_BRANCH(64_byte_Tapret_Commitment) |
          +------------^-------^---+               +--------------------------------------+
                       |       |
             +---------+       +-----------+
             |                             |
+------------+----------+           +------+-----+
| tH_BRANCH(tHA || tHB) |           | tH_LEAF(C) |
+------------^------^---+           +------^-----+
             |      |                      |
      +------+      +------+               |
      |                    |               |
+-----+------+       +-----+------+        |
| tH_LEAF(A) |       | tH_LEAF(B) |        |
+-----^------+       +-----^------+        |
      |                    |               |
    +-+-+                +-+-+           +-+-+
    | A |                | B |           | C |
    +---+                +---+           +---+
```

**2)** According to Taproot rules, **every branch and leaf hashing operation is performed in lexicographic order of the two operands**.

Therefore, **three cases** that lead to two different proofs of uniqueness of the commitment can occur.

**a)** If the hash of the Tapret commitment (`tHT`) **is greater** than the top-level hash of the Script Path Spend (`tHABC`), it will be put on **the right side of the Script Tree**. In this case, the commitment at this position is considered as a valid proof of uniqueness. The related Merkle Proof of inclusion and uniqueness consists of `tHABC` and `P` only, as shown in the diagram below.

<pre><code><strong>* tHABC &#x3C; tHT case
</strong>
+---+            +---+   +---+   +---+
| Q |      =     | P | + | t | * | G |
+---+            +---+   +-^-+   +---+
                           |
                           +--------------------+
                                                |
                                +---------------+------------+
                                | tH_TWEAK(P || Script_root) |
                                +---------------------^------+
                                                      |
                                       +--------------+----------+
                                       | tH_BRANCH(tHABC || tHT) |
                                       +-------------^-------^---+
                                                     |       |
                     +-------------------------------+       +-------+
                     |                                               |
          +----------+-------------+               +-----------------+--------------------+
          | tH_BRANCH(tHAB || tHC) |               | tH_BRANCH(64_byte_Tapret_Commitment) |
          +------------------------+               +--------------------------------------+
</code></pre>

**b)** If the hash of the tapret commitment (`tHT`) **is smaller** than the top-level hash of the Script Path Spend (`tHABC`), it will be placed on **the left side of the Script Tree**. In this case, it is necessary to show that there are no other Tapret commitments on the right side of the Tree. To do this, two cases must be taken into account:

**b1)** If the old root is a merkle node with two branches, `tHAB` and `tHC` must be revealed and form the Merkle proof of inclusion and uniqueness along with `P`, as shown in the diagram below:

```
* tHABC > tHT case (branch)

+---+            +---+   +---+   +---+
| Q |      =     | P | + | t | * | G |
+---+            +---+   +-^-+   +---+
                           |
                           +--------------------+
                                                |
                                +---------------+------------+
                                | tH_TWEAK(P || Script_root) |
                                +---------------------^------+
                                                      |
                                       +--------------+----------+
                                       | tH_BRANCH( tHT || tHABC)|
                                       +-------------^-------^---+
                                                     |       |
                                  +------------------+       +------------------+
                                  |                                             |
             +--------------------+-----------------+              +------------+-----------+
             | tH_BRANCH(64_byte_Tapret_Commitment) |              | tH_BRANCH(tHAB || tHC) |
             +--------------------------------------+              +------------^-------^---+
                                                                                |       |
                                                                   +------------+       +--------+
                                                                   |                             |
                                                      +------------+----------+           +------+-----+
                                                      | tH_BRANCH(tHA || tHB) |           | tH_LEAF(C) |
                                                      +-----------------------+           +------------+
```

*Note:* although the tapret commitment is the same length of two concatenated hashes (64 bytes), it's not possible to hide an alternative commitment by splitting it into two fake subtree roots since the taproot hashing strategy (tag + encoded data) for branches is different from the one for leaves. Therefore, no extra checks are required on the values of `tHAB` and `tHC`.

**b2)** If the old root is itself a leaf node, then the leaf content must be revealed and form the Merkle proof of inclusion and uniqueness along with `P`, as shown in the diagram below:

```
* tHABC > tHT case (leaf)

+---+            +---+   +---+   +---+
| Q |      =     | P | + | t | * | G |
+---+            +---+   +-^-+   +---+
                           |
                           +--------------------+
                                                |
                                +---------------+------------+
                                | tH_TWEAK(P || Script_root) |
                                +---------------------^------+
                                                      |
                                       +--------------+----------+
                                       | tH_BRANCH( tHT || tHC)|
                                       +-------------^-------^---+
                                                     |       |
                                  +------------------+       +------------------+
                                  |                                             |
             +--------------------+-----------------+                    +------+-----+
             | tH_BRANCH(64_byte_Tapret_Commitment) |                    | tH_LEAF(C) |
             +--------------------------------------+                    +------------+
```

## **Nonce optimization**

The above construction is clearly more complex and the proof is larger when the tapret commitment lies in the left side of the tree, since more details on the rest of the taproot tree need to be revealed. In particular, in the **b2** scenario, in case `tH_LEAF(C)` contains spending conditions that should remain private, one may want to hide it by adding a dummy leaf that turns this into a **b1** case. However, this would make such spending conditions more expensive to spend onchain, leading to a privacy vs cost tradeoff.

To avoid this complexity, the `<Nonce>` encoded in the last byte of the `64_byte_Tapret_Commitment` allows the prover to attempt at "mining" a `tHT` such that `tHABC < tHT`, thus placing it in the right-hand side of the tree and definitely avoiding revealing the constituents of the script branch (in this example: either `tHAB || tHC` or `tH_LEAF(C)`).

***


# Multi Protocol Commitments - MPC

Multi Protocol Commitments address the following important requirements:

1. How the tagged `mpc::Commitment` hash, committed in Bitcoin Blockchain according to `Opret` or `Tapret` schemes, is constructed.
2. How state changes associated with more than one contract can be stored in a single commitment.

The preceding points are addressed through an **ordered merkelization** of the multiple contracts (actually their [transition bundles](/annexes/glossary#transition-bundle) IDs) in an [MPC](/annexes/glossary#multi-protocol-commitment-mpc) Tree whose properties will be addressed in depth in this section. Eventually, the root of the tree (`mpc::Root`) is hashed once more to get the `mpc:Commitment` which is finally committed in an output of the [witness transaction](/annexes/glossary#witness-transaction) using the appropriate [Deterministic Bitcoin Commitment](/annexes/glossary#deterministic-bitcoin-commitment-dbc) construction.

<figure><img src="/files/sX0DRkXxIA1g5T1eDbfD" alt=""><figcaption><p><strong>Each RGB contract has a unique position in the MPC Tree determined by a modular division applied to its ContractId according to the width of the tree. In this example, the MPC tree has a width of 8.</strong></p></figcaption></figure>

## MPC Root Hash

The commitment of the MPC tree - which goes either into [Opret](/commitment-layer/deterministic-bitcoin-commitments-dbc/opret) or into [Tapret](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret) commitments - is the `mpc::Commitment` constructed in BIP-341 fashion as follows:

`mpc::Commitment = SHA-256(SHA-256(mpc_tag) || SHA-256(mpc_tag) || depth || cofactor || mpc::Root )`

Where:

* `mpc_tag = urn:ubideco:mpc:commitment#2024-01-31` follows [RGB tagging conventions](/annexes/commitments#specific-rgb-consensus-commitments).
* `depth` is the depth of the tree as a single byte
* `cofactor` is the value used to obtain distinct positions for the contracts in the tree as a 16-bit Little Endian unsigned integer (see [MPC Tree Construction](#mpc-tree-construction))
* `mpc::Root` is the root of the MPC tree whose construction is explained in the following paragraphs.

## MPC Tree Construction

In order to construct the MPC tree we must **deterministically find a unique leaf position for each contract**, thus:

By setting `C` the number of contracts and `i = {0,1,..,C-1}` and by having a `ContractId(i) = c_i` to be included in the MPC, we can construct a tree with `w` leaves with `w > C` (corresponding to a depth `d` such that `2^d = w`), so that each contract identifier `c_i` representing a different contract is placed in a unique position `pos(c_i)` determined as a modulus operation detailed below.

In essence, the construction of a suitable tree of width `w` that hosts each contract `c_i` in a unique position represents a kind of mining process. The greater the number of contract `C`, the greater should be the number of leaves `w`. Assuming a random distribution of `pos(c_i)`, as per [Birthday Paradox](https://en.wikipedia.org/wiki/Birthday_problem), we have \~50% probability of a collision occurring in a tree with `w ~ C^2`.

In order to avoid too large MPC trees and assuming that the occurrence of collisions is a random process, an additional optimization has been introduced.

The actual formula for determining the **leaf position of the contract** is:

```
pos(c_i) = c_i mod (w - cofactor)
```

Where `cofactor` is a number that allows to increase the chance of deterministically obtaining distinct values of `pos(c_i)` with a given `w`.

The tree construction process starts from the smallest tree such that `w > C` and performing a certain number of `cofactor` attempts; if none of them can produce `C` distinct positions, `d` is incremented by one and a new series of `cofactor` trials is attempted. In particular, `cofactor` is chosen starting from `0` and trying every number up to `w/2`: larger values cannot succeed since otherwise it would have been possible to build a tree of depth `d-1`.

### **Contract Leaves (Inhabited)**

Once `C` distinct positions `pos(c_i)` with `i = 0,...,C-1` are found, the corresponding leaves are populated through a tagged hash constructed in the following way:

`tH_MPC_LEAF(c_i) = SHA-256(SHA-256(merkle_tag) || SHA-256(merkle_tag) || 0x10 || c_i || BundleId(c_i))`

Where:

* `merkle_tag = urn:ubideco:merkle:node#2024-01-31` is chosen according to [RGB conventions on Merkle Tree tagging commitments](/annexes/commitments#merklization-procedure).
* `0x10` is the integer identifier of contract leaves.
* `c_i` is the 32-byte contract\_id which is derived from the hash of the [Genesis](/rgb-state-and-operations/state-transitions#genesis) of the contract itself.
* `BundleId(c_i)` is the 32-byte hash that is calculated from the data of the [Transition Bundle](/rgb-state-and-operations/state-transitions#transition-bundle) which groups all the [State Transitions](/annexes/glossary#state-transition) of the contract `c_i`.

### **Entropy leaves (Uninhabited)**

For the remaining `w - C` uninhabited leaves, a dummy value must be committed. To do that, each leaf in position `j != pos(c_i)` is populated in the following way:

`tH_MPC_LEAF(j) = SHA-256(SHA-256(merkle_tag) || SHA-256(merkle_tag) || 0x11 || entropy || j )`

Where:

* `merkle_tag = urn:ubideco:merkle:node#2024-01-31` is chosen according to [RGB conventions on Merkle Tree tagging commitments](/annexes/commitments#merklization-procedure).
* `0x11` is the integer identifier of entropy leaves.
* `entropy` is a 64-byte random value chosen by the user constructing the tree.
* `j` is the position of the current leaf as a 32-bit Little Endian unsigned integer.

### MPC nodes

After generating the base of the MPC tree having `w` leaves, merkelization is performed following the rule of `commit_verify` crate detailed [here](/annexes/commitments#merklization-procedure).

The hash for non-leaf nodes in the tree is computed as:

`tH_MPC_BRANCH(tH1 || tH2) = SHA-256(SHA-256(merkle_tag) || SHA-256(merkle_tag) || b || d || w || tH1 || tH2)`

Where:

* `merkle_tag = urn:ubideco:merkle:node#2024-01-31` is chosen according to [RGB conventions on Merkle Tree tagging commitments](/annexes/commitments#merklization-procedure).
* `b` is the branching of the tree merkelization scheme, i.e. the number of children the current node has, encoded as a 8-bit unsigned integer. If the tree is complete, this is always `0x02`.
* `d` is the node depth within the tree (i.e. the length of the path to the root), encoded as an 8-bit unsigned integer.
* `w` is the tree width, encoded as a 256-bit Little Endian unsigned integer.
* `tH1` and `tH2` are respectively the hash of the left and the right child, calculated according to the appropriate formula depending on their role in the tree (contract leaf, entropy leaf or merkle node).

The following diagram shows the construction of an example MPC tree, where:

* `C = 3` number of contracts to place.
* As an example: `pos(c_0) = 7, pos(c_1) = 4, pos(c_2) = 2`.
* `BUNDLE_i = BundleId(c_i)`.
* `d` depends on the position of the node within the tree; for example, `tH_MPC_BRANCH(tHA || tHB)` has `d=2`.
* `w=8` for every node in the tree.

{% code fullWidth="true" %}

```
                                                                                   +--------------------------+
                                                                   mpc:Root        | th_MPC(tHABCD || tHEFGH) |
                                                                                   +-----------^---------^----+
                                                                                               |         |
                                              +------------------------------------------------+         +--------------------------------------------+
                                              |                                                                                                       |
                                +-------------+---------------+                                                                         +-------------+---------------+
                                | tH_MPC_BRANCH(tHAB || tHCD) |                                                                         | tH_MPC_BRANCH(tHEF || tHGH) |
                                +----------------^--------^---+                                                                         +-----------------+--------+--+
                                                 |        |                                                                                               |        |
                     +---------------------------+        +--------------+                                                   +------------------<---------+        +------------+
                     |                                                   |                                                   |                                                  |
       +-------------+-------------+                       +-------------+-------------+                       +-------------+-------------+                      +-------------+-------------+
       | tH_MPC_BRANCH(tHA || tHB) |                       | tH_MPC_BRANCH(tHC || tHD) |                       | tH_MPC_BRANCH(tHE || tHF) |                      | tH_MPC_BRANCH(tHG || tHH) |
       +----------------^------^---+                       +----------------^------^---+                       +----------------^------^---+                      +----------------^------^---+
                        |      |                                            |      |                                            |      |                                           |      |
         +--------------+      +-----+                       +--------------+      +- ---+                       +--------------+      + ----+                      +--------------+      +-----+
         |                           |                       |                           |                       |                           |                      |                           |
 +-------+--------+        +---------+------+        +-------+--------+        +---------+------+        +-------+--------+        +---------+------+        +------+---------+        +--------+-------+
 | tH_MPC_LEAF(A) |        | tH_MPC_LEAF(B) |        | tH_MPC_LEAF(C) |        | tH_MPC_LEAF(D) |        | tH_MPC_LEAF(E) |        | tH_MPC_LEAF(F) |        | tH_MPC_LEAF(G) |        | tH_MPC_LEAF(H) |
 +-------------^--+        +-------------^--+        +-------------^--+        +-------------^--+        +-------------^--+        +-------------^--+        +-------------^--+        +-------------^--+
               |                         |                         |                         |                         |                         |                         |                         | 
+--------------+-------+  +--------------+-------+  +--------------+----------+  +-----------+---------+  +------------+------------+  +---------+------------+  +---------+------------+  +---------+---------------+ 
| 0x11 || entropy || 0 |  | 0x11 || entropy || 1 |  | 0x10 || c_2 || BUNDLE_2 |  | 0x11 | entropy || 3 |  | 0x10 || c_1 || BUNDLE_1 |  | 0x11 || entropy || 5 |  | 0x11 || entropy || 6 |  | 0x10 || c_0 || BUNDLE_0 | 
+----------------------+  +----------------------+  +-------------------------+  +---------------------+  +-------------------------+  +----------------------+  +----------------------+  +-------------------------+
```

{% endcode %}

### MPC Tree Verification

From a verifier's perspective, in order to prove the presence of client-side validated data related to some contract `c_i` collected in `BUNDLE_i`, **only a Merkle Proof pointing at it inside the tree is needed**. Because of this, different verifiers of different contracts don't need to have the full view of the Merkle Tree as the builder does, and this, together with the dummy entropy leaves, provides a high degree of privacy. Using the example tree in the diagram above, a verifier of, say, the contract `c_2` will receive the following *Merkle Proof* from the tree builder:

{% code fullWidth="true" %}

```
                                                                            +-------------------------------+
                                                                            | tH_MPC_ROOT(tHABCD || tHEFGH) |
                                                                            +----------------^---------^----+
                                                                                             |         |
                                       +-----------------------------------------------------+         +---------------------------------------+
                                       |                                                                                                       |
                         +-------------+---------------+                                                                         +-------------+---------------+
                         | tH_MPC_BRANCH(tHAB || tHCD) |                                                                         | tH_MPC_BRANCH(tHEF || tHGH) |
                         +----------------^--------^---+                                                                         +-----------------------------+
                                          |        |
              +---------------------------+        +--------------+
              |                                                   |
+-------------+-------------+                       +-------------+-------------+
| tH_MPC_BRANCH(tHA || tHB) |                       | tH_MPC_BRANCH(tHC || tHD) |
+---------------------------+                       +----------------^------^---+
                                                                     |      |
                                                      +--------------+      +- ---+
                                                      |                           |
                                              +-------+--------+        +---------+------+
                                              | tH_MPC_LEAF(C) |        | tH_MPC_LEAF(D) |
                                              +-------------^--+        +-------------^--+
                                                            |                          
                                             +-------------------------+                                                                                                                                    
                                             | 0x10 || c_2 || BUNDLE_2 |                                                                                                                                    
                                             +-------------------------+                                                                                                                                    
```

{% endcode %}

So the Merkle Proof provided to verify the existence and uniqueness of contract commitment in the tree is: `tH_MPC_LEAF(D)`, `tH_MPC_BRANCH(tHA || tHB)` and `tH_MPC_BRANCH(tHEF || tHGH)`. These are enough to recompute the tree root and, together with `pos(c_2)` and `cofacor`, reproduce the MPC commitment to be compared with the one included in the anchor.


# Anchors

Anchors are the client-side validated structures that summarize all the data needed to validate contract commitments, which were described in the previous section. They are composed of the following ordered fields:

* `Txid`
* `MPC Proof`
* `Extra Transaction Proof ETP`

Where:

## TxId

`Txid` is the 32-byte ID of the transaction containing the Opret / Tapret commitment. Note that `TxId` could theoretically be reconstructed from the off-chain data of [state transitions](/annexes/glossary#state-transition) pointing to each [witness transaction](/annexes/glossary#witness-transaction) and thus following the chain of [single-use seals](/annexes/glossary#single-use-seal). However, to simplify the validation task, they are included in the anchor.

## MPC Proof

The `MPC Proof` of the contract `c_i` consists of `depth`, `cofactor` and `Merkle Proof` which were described [previously](/commitment-layer/multi-protocol-commitments-mpc#mpc-tree-construction).

## Extra Transaction Proof - ETP

If an [Opret](/commitment-layer/deterministic-bitcoin-commitments-dbc/opret) commitment is used, no additional proof is provided in this field, since, as described in [the previous section](/commitment-layer/deterministic-bitcoin-commitments-dbc/opret), the verifier inspects the first `OP_RETURN` output finding the correct `mpc::Commitement`.

If a [Tapret](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret) commitment is used, a so called **Extra Transaction Proof - ETP** must be provided, which consists of:

* Internal Public Key `P` of the Taproot output used.
* Partner node(s) of the [Taproot](/annexes/glossary#taproot) `Script Path Spend` which is either:
  * The top left branch (in the [example](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret#tapret-incorporation-in-pre-existing-script-path-spend): `tHABC`) if the `Tapret` commitment is on the right side of the tree.
  * The left and right nodes of the upper right branch (in the same example they are: `tHAB` and `tHC`) if the `Tapret` commitment is on the left side of the tree.
* The [nonce](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret#nonce-optimization), if used, to optimize the Partner node part of the proof.

In the next section, we will introduce concepts purely concerning the off-chain part of RGB, i.e. contracts, giving an abstract view of the partially replicated finite state machine that gives RGB a much greater expressiveness than can be achieved through Bitcoin Script without sacrificing confidentiality.

***


# Introduction to Smart Contracts and their States

Before addressing the technical implementation of **RGB states** and the related data structure, it is important to remember that the ordered sequence of [single-use seals](/annexes/glossary#single-use-seal) is intended to provide the ability to properly implement the various [Contract Operations](/annexes/glossary#contract-operation) in the client-side validated domain.

\
After a brief introduction to [smart contracts](/annexes/glossary#contract) and [state](/annexes/glossary#contract-state) concepts, we will devote our attention to the mechanism behind **Contract Operations** from the the Client-side perspective and the related bridging *points which* tether these operations to the Bitcoin Blockchain commitments discussed in the [commitment layer section](/commitment-layer/commitment-schemes).

## Smart Contracts and Digital Bearer Rights

Since RGB allows for the implementation of **smart contracts** in Bitcoin, it is a good time to define what a smart contract actually is.

> A **smart contract** is an agreement which is automatically and computationally enforced between the parties.

This means that the enforcement of the terms agreed upon between the parties **does not require human intervention** and that such enforcement is carried out by mathematical and computerized means.

Furthermore, a question arises. To achieve the highest degree of automation, decentralization, and privacy, is it possible to forfeit the use of a centralized registry that stores ownership and contract information? The affirmative answer lies back at the origins.

![RGB enables digital version of bearer instruments.](/files/3pzOa4NmYA6FB07aHYqM)

Not long times ago, contracts, such as securities, were **bearer instruments**. Indeed, the widespread use of asset registers that imply a custodial relationship with some institution on behalf of the client is a fairly recent development in economic history. **The bearer nature of contracts is, in fact, a centuries-old tradition.** This type of philosophy is the basis of the RGB architecture, in that **the bearer** rights of each claimant **are contained in the form of data within the contract** and can be modified and applied digitally, following the rules of the contract itself.

## Introduction to States

A wider range of smart contract programmability issues were considered in the design of RGB, in particular:

1. **A contract can be associated with a digital asset or a token, but it's not limited to it**. A broader range of applications and extensions of the *smart contract* concept can be implemented in RGB.
2. Unlike the approach of other public blockchains to smart contracts, in **RGB there is a clear separation between the different** [parties](/annexes/glossary#contract-participant) **related to a contract and their rights**: e.g. the creator/issuer of the contract and the different kinds of users interacting in some ways with the contract. This includes, in particular, the differentiation between:
   * the ability to *observe* certain properties or operations performed by other parties on the contract;
   * the ability to *execute a set of operations* permitted by the contract.

**No other counterparty can interact** with the operations performed on the contract unless it is authorized by the rightful parties. Within RGB this feature means that there is always an [owner](/annexes/glossary#ownership) that has the right to perform certain operations on the contract, which are defined by the contract itself.

These properties combined allow for two of the most important properties at the heart of the RGB value proposition, which are: **scalability** and **censorship resistance** at unprecedented levels.

In order to achieve these goals, an RGB contract is composed of two main components:

* **State**
* **Business Logic (Behavior)**

The [Business Logic](/annexes/glossary#business-logic) of the contract represents the rules that allow the entitled parties to change the state of the contract. We will find out later that the **Business Logic** is embedded in a particular structure of the contract called the [Schema](/annexes/glossary#schema).

![In order to evolve, smart contract states must fallow a business logic.](/files/ss84tXyrmlzeAslRLYF7)

Without going into the specific details of RGB implementation, which will be covered [later](/rgb-state-and-operations/state-transitions), an initial and fundamental definition of [State](/annexes/glossary#contract-state) is required. Simply put:

> A **State** can be defined as a unique configuration of information or data that represents the conditions of a contract at a specific point in time.

Therefore, a [Contract Operation](/annexes/glossary#contract-operation), in general terms, represents any **first creation/update of data** from an **old state** to a **new state** following the **rules inscribed into the contract** constituting its **Business Logic**.

<figure><img src="/files/ET4CsKPTpHyo5RTkspLS" alt=""><figcaption><p><strong>State Transitions (among Contract Operations) apply business logic to an Old state to derive a New state.</strong></p></figcaption></figure>

The chain of Contract Operations in RGB is the ordered path that evolves the contract data from the **first contract definition**, called [Genesis](/annexes/glossary#genesis), to the Terminal State that represents the most up-to-date state at the end of the [DAG](/annexes/glossary#directed-acyclic-graph-dag) of Contract Operations.

The ordering relationship within the DAG is maintained by operations committing to their inputs and guaranteed by their anchors to the Bitcoin Blockchain which, in turn, provides timestamping capabilities. It's worth noting that a given chain of RGB transitions does necessarily correspond to a chain of Bitcoin transactions, which means that the onchain order of anchor transactions does not allow to infer the ordering of the respective DAG nodes.

***


# 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](/commitment-layer/commitment-schemes#txo2-client-side-validation) 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](/annexes/glossary#utxo). Let's see how the process works in practice for a [State Transition](/annexes/glossary#state-transition) (one of the fundamental [Contract Operations](/annexes/glossary#contract-operation)):

1. Alice has a [stash](/annexes/glossary#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](/annexes/glossary#seal-definition) that points to one of her UTXOs.

<figure><img src="/files/ARbzp1nkhpxRQ3ch2IZB" alt=""><figcaption><p>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.</p></figcaption></figure>

2. 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.

<figure><img src="/files/bpstnyeVO6d2MDYtSXcF" alt=""><figcaption><p><strong>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.</strong></p></figcaption></figure>

3. Bob, through some informational data, encoded in an [invoice](/annexes/glossary#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](/rgb-state-and-operations/components-of-a-contract-operation#revealed-concealed-form)). In this way, Alice assigns Bob **some ownership** of the new state: for example, ownership of a certain amount of tokens.

<figure><img src="/files/PoSztMAjxgTIjL4WJPXN" alt=""><figcaption><p><strong>Bob shares with Alice the necessary data to build the State Transition that assigns him some new state.</strong></p></figcaption></figure>

4. After that, Alice, using some [PSBT](/annexes/glossary#partially-signed-bitcoin-transaction-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](/annexes/glossary#witness-transaction), Alice embeds in one output a commitment to the new state data that uses [Opret](/commitment-layer/deterministic-bitcoin-commitments-dbc/opret) or [Tapret](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret) rules depending on the chosen method. As explained earlier, Opret or Tapret commitments are derived from an [MPC](/annexes/glossary#multi-protocol-commitment-mpc) tree which may collect more than one contract's state transition.
5. Before transmitting the transaction thus prepared, Alice passes to Bob a data packet called [Consignment](/rgb-state-and-operations/state-transitions) 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, proving the **legitimacy** of the allocations' history.
   * **Verifies** that every RGB state transition **is committed to in a valid** [**witness transaction**](/annexes/glossary#witness-transaction), ensuring that the corresponding seals are properly closed. This implies the **completeness** of the history from Genesis to the new state, since spending an allocation requires closing the corresponding seal, which is defined by the parent transition and must be present in **revealed** form in the consignment for the validation to pass.
6. After checking the correctness of the Consignment, Bob may optionally give Alice a "go-ahead" signal (e.g., by GPG signing the [consignment](/annexes/glossary#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](/annexes/glossary#state-transition) from Alice to Bob.

For the detailed process of a contract transfer with the RGB stack, see the [related section](/annexes/contract-transfers).

<figure><img src="/files/njG8Urcld098Ab54m3Se" alt=""><figcaption><p>T<strong>he 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.</strong></p></figcaption></figure>

It's useful to see the full details of a DAG of two RGB contract operations - ([Genesis](/annexes/glossary#genesis) + a [State Transition](/annexes/glossary#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.](/files/k0kAh13Nv7Za21E0ybZl)

Just to give an introduction to the context of the above diagram, let us introduce terminology that will be discussed [later](/rgb-state-and-operations/components-of-a-contract-operation) in greater technical detail:

* The [Assignment](/annexes/glossary#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](/annexes/glossary#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](/annexes/glossary#owned-state) 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](/annexes/glossary#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](/rgb-state-and-operations/intro-smart-contract-states#introduction-to-states), a State Transition represents the main form within [Contract Operations](/annexes/glossary#contract-operation) (in addition to [Genesis](/annexes/glossary#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.](/files/NFMzmyGwuh2iIhMMR5I7)

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](/annexes/glossary#multi-protocol-commitment-mpc) tree:

* A [Transition Bundle](#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](#bundleid), which is included in a leaf of the [MPC](/annexes/glossary#multi-protocol-commitment-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](/annexes/glossary#deterministic-bitcoin-commitment-dbc), so that the bitcoin transaction unequivocally commits to a set of RGB state transitions.
* The [Anchor](/commitment-layer/anchors) 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 Consensus Library](/annexes/rgb-library-map#rgb-consensus).

## 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](/annexes/glossary#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](/annexes/glossary#assignment) 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](/rgb-state-and-operations/state-transitions) is [obtained](/annexes/commitments#bundle-id) 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](/annexes/glossary#contract-operation) 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.

```mermaid
block-beta
  columns 7
  block:group1:3
    columns 3
    space t1(["RGB Contract"]) space
    space G("Genesis") space
    space space space
    space C0(" ") C1(" ")
    space space space
    space C2(" ") space
    space space space
    space C3(" ") space
    space space space
    C4(" ") C5(" ") space
    space space space
    C6(" ") C7(" ") space
    space space space
    space C8(" ") space
  end
  space
  block:group2:1
    columns 1
    t2(["Anchors"])
    space
    A0(" ")
    A1(" ")
    space
    A2(" ")
    space
    A3(" ")
    space
    A4(" ")
    space
    A5(" ")
    A6(" ")
    A7(" ")
  end
  space
  block:group3:1
    columns 1
    t3(["Blockchain"])
    B0(" ")
    space
    B1(" ")
    space
    B2(" ")
    space
    B3(" ")
    space
    B4(" ")
    space
    B5(" ")
    space
    B6(" ")
  end

  %% contract DAG
  G --> C0
  G --> C1
  C0 --> C2
  C1 --> C3
  C2 --> C3
  C2 --> C4
  C3 --> C5
  C4 --> C6
  C5 --> C7
  C6 --> C8
  C7 --> C8

  %% blockchain relationships
  B0 --> B1
  B1 --> B2
  B2 --> B3
  B3 --> B4
  B4 --> B5
  B5 --> B6

  %% transitions included in anchors
  C0 --> A1
  C1 --> A0
  C2 --> A2
  C3 --> A3
  C4 --> A3
  C5 --> A4
  C6 --> A6
  C7 --> A5
  C8 --> A7

  %% anchors included in blocks
  A0 --> B0
  A1 --> B1
  A2 --> B1
  A3 --> B2
  A4 --> B4
  A5 --> B5
  A6 --> B5
  A7 --> B6

  %% style
  style C0 fill:#ED2939,stroke:#ED2939
  style C1 fill:#ED2939,stroke:#ED2939
  style C2 fill:#ED2939,stroke:#ED2939
  style C3 fill:#ED2939,stroke:#ED2939
  style C4 fill:#ED2939,stroke:#ED2939
  style C5 fill:#ED2939,stroke:#ED2939
  style C6 fill:#ED2939,stroke:#ED2939
  style C7 fill:#ED2939,stroke:#ED2939
  style C8 fill:#ED2939,stroke:#ED2939

  style A0 fill:#808080,stroke:#808080
  style A1 fill:#808080,stroke:#808080
  style A2 fill:#808080,stroke:#808080
  style A3 fill:#808080,stroke:#808080
  style A4 fill:#808080,stroke:#808080
  style A5 fill:#808080,stroke:#808080
  style A6 fill:#808080,stroke:#808080
  style A7 fill:#808080,stroke:#808080

  style B0 fill:#F98129,stroke:#F98129
  style B1 fill:#F98129,stroke:#F98129
  style B2 fill:#F98129,stroke:#F98129
  style B3 fill:#F98129,stroke:#F98129
  style B4 fill:#F98129,stroke:#F98129
  style B5 fill:#F98129,stroke:#F98129
  style B6 fill:#F98129,stroke:#F98129
```

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](/rgb-state-and-operations/state-transitions) 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](/annexes/glossary#contract-participant) 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](/annexes/glossary#schema), are defined several properties affecting deeply the contract states, both of [owned](/annexes/glossary#owned-state) and [global](/annexes/glossary#global-state) 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.

***


# Components of a Contract Operation

Let's now deep-dive into all the components of a [Contract Operation](/annexes/glossary#contract-operation), which are capable of changing the state of the contract and which are ultimately verified client-side by the legitimate recipient in a deterministic manner.

{% code fullWidth="true" %}

```
               +---------------------------------------------------------------------------------------------------------------------+
               |  Contract Operation                                                                                                 |
               |                                                                                 +-----------------------+           |
               |                                                                                 | ChainNet              |           |
               |  +-----+         +-----------------------+          +----------------+          | +-------+ +---------+ |           |
               |  | Ffv |         | ContractId | SchemaId |          | TransitionType |          | | Chain | | Network | |           |
               |  +-----+         +-----------------------+          +----------------+          | +-------+ +---------+ |           |
               |                                                                                 +-----------------------+           |
               |  +-----------------------------------------------+  +------------------------------------------------------------+  |
               |  | Metadata                                      |  | Global State                                               |  |
               |  |                                               |  | +----------------------------------+                       |  |
               |  | +-------------------------------------+       |  | | +-------------------+ +--------+ |                       |  |
               |  | |          Structured Data            |       |  | | |  GlobalStateType  | |  Data  | |     ...     ...       |  |
               |  | +-------------------------------------+       |  | | +-------------------+ +--------+ |                       |  |
               |  |                                               |  | +----------------------------------+                       |  |
               |  +-----------------------------------------------+  +------------------------------------------------------------+  |         +------+
               |                                                                                                                     +---------> OpId |
               |  +-----------------------------------------------+  +------------------------------------------------------------+  |         +------+
               |  | Inputs                                        |  | Assignments                                                |  |
               |  |                                               |  |                                                            |  |
               |  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
               |  | | Input #1                                  | |  | | Assignment #1                                          | |  |
+------+       |  | | +----------+ +----------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
| OpId +--------------> PrevOpId | | AssignmentType | | Index | | |  | | | AssignmentType | | Owned State | | Seal Definition +--------------> Bitcoin UTXO |
+------+       |  | | +----------+ + ---------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
               |  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
               |  |                                               |  |                                                            |  |
               |  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
               |  | | Input #2                                  | |  | | Assignment #2                                          | |  |
+------+       |  | | +----------+ +----------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
| OpId +--------------> PrevOpId | | AssignmentType | | Index | | |  | | | AssignmentType | | Owned State | | Seal Definition +--------------> Bitcoin UTXO |
+------+       |  | | +----------+ +----------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
               |  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
               |  |                                               |  |                                                            |  |
               |  |       ...           ...          ...          |  |     ...          ...             ...                       |  |
               |  |                                               |  |                                                            |  |
               |  +-----------------------------------------------+  +------------------------------------------------------------+  |
               |                                                                                                                     |
               +---------------------------------------------------------------------------------------------------------------------+
```

{% endcode %}

With the help of the comprehensive diagram above, it's important to point out that any contract operation is composed of some components related to the **New State** and some components that reference the **Old State** being updated.

The **Old State** is referenced through [Inputs](#inputs), which point towards previous assignments of related State Transitions and are not found in Genesis.

The **New state** is represented by:

* **Assignments**, which are composed by:
  * [Seal Definition](#seal-definition).
  * [Owned State](#owned-states).
* [Global State](#global-state), which can be either [mutated or added](#state-update-methods-and-rules).
* [Metadata](#metadata), which are only available locally to the current operation.

In addition, we also have several operation-specific fields:

* `Ffv` or `Fast-forward version` a 2-byte integer indicating the version of the contract, following the RGB rules of [fast-forward versioning](/rgb-state-and-operations/features-of-rgb-state#rgb-consensus-changes). The version of the contract can be updated according to the issuer's choices and needs at certain points in the contract's history, such as concerning *inflations.*
* `TransitionType` a 16-bit integer indicating the type of Transition expressed by the operation encoded in the Contract [Schema](/annexes/glossary#schema) and representing the manifestation of the [Business Logic](/annexes/glossary#business-logic) of the contract. It's not present in [Genesis](/annexes/glossary#genesis).
* `ContractId` the 32-byte number that references the `OpId` of the Genesis of the contract. Naturally, it's only present in State Transitions, but not in Genesis.
* `SchemaId` is a field found only in Genesis, instead of the `ContractId`. It's a 32-byte hash of the contract [Schema](/annexes/glossary#schema) used in the contract.
* `Testnet` is a boolean variable indicating the use of Bitcoin Testnet or Mainnet. It is only present in Genesis.
* `ChainNet` is an object that describes the context in which the contract should operate; it is composed by `Chain` (e.g. Bitcoin, [Liquid](https://blockstream.com/liquid/)) and `Network` (e.g. `Mainnet`, `Testenet`). It is only present in Genesis.
* `Metadata` that allows you to declare temporary variables that are useful for validating complex contracts, but that do not have to be recorded as [state](/annexes/glossary#contract-state) properties.

Finally, through a custom hashing methodology, all of the fields in the Contract Operation are summarized into an `OpId` commitment that is placed in the [Transition Bundle](/rgb-state-and-operations/state-transitions#transition-bundle).

## OpId

Each Contract Operation is identified by a 32-byte hash called `OpId`, which is, precisely, the ordered SHA-256 hashing of the element contained in the State Transition. Each contract operation has its own customized [commitment and hashing methodology](/annexes/commitments#operation-id-and-contract-id).

## ContractId

As an important additional feature, the `ContractId` of a smart contract is calculated by using the `OpId` of its [Genesis](/annexes/glossary#genesis) and applying to it a *Reverse byte order operation* plus a [Base58](https://en.wikipedia.org/wiki/Binary-to-text_encoding#Base58) encoding.

## Contract State

Before addressing each state component, it's essential to clarify through which elements a [Contract State](/annexes/glossary#contract-state) is expressed in the RGB protocol. Specifically, in RGB, the **State** of a contract is fully expressed by:

* A single **Global State**
* One or more **Owned State(s)** that are controlled by some contract participants

Global States are embedded into Contract Operation as a single component block, while [Owned States](/annexes/glossary#owned-state) are defined inside the [Assignment](/annexes/glossary#assignment) construct where they are stored alongside the pertaining [Seal Definition](/annexes/glossary#seal-definition).

### State update methods and rules

An important feature of RGB, which **affects both Global and Owned States, is the way the state is modified**. Basically, States may exhibit two different behaviors:

* A **Mutable** behavior, in which **each state transition discards the previous state** and assigns a new one.
* An **Accumulating** behavior, in which each state transition adds a new state to the previous state.

In all cases where the **Contract State is neither Mutated nor Accumulated, the respective components are left empty**, meaning that no repetition of data takes place in a Contract Operation.

The choice between mutable or accumulated state is set inside the [Business Logic](/annexes/glossary#business-logic) encoded in the [Schema](/annexes/glossary#schema) of the contract and cannot be changed after the Genesis.

The table below provides a summary of the rules regarding the permitted modification of Global/Owned States by each Contract Operation, if allowed by contract schema:

|                          | **Genesis** | **State Transition** |
| ------------------------ | :---------: | :------------------: |
| **Adds Global State**    |      ✓      |           ✓          |
| **Mutates Global State** |      ✗      |           ✓          |
| **Adds Owned State**     |      ✓      |           ✓          |
| **Mutates Owned State**  |      ✗      |           ✓          |

As a final consideration of this section, in the following table we provide a summary of the main scope-related properties that the various kind of state data elements exhibit in the RGB protocol.

|                    |             **Metadata**            |                   **Global state**                  |                                             **Owned state**                                            |
| ------------------ | :---------------------------------: | :-------------------------------------------------: | :----------------------------------------------------------------------------------------------------: |
| **Scope**          |    Defined per contract operation   |            Defined per contract globally            |                                Defined per single-use-seal (Assignment)                                |
| **Who can update** |            Not updatable            |                  Operation creators                 |                   Controlled by right owners (parties able to close single-use-seal)                   |
| **Time scope**     | Defined just for a single operation | State is defined after/as a result of the operation | State is defined before the operation (when the seal definition is embedded in the previous operation) |

### Global State

The purpose of Global State can be summarized by the following sentence:**"nobody owns, everyone knows"** in that it defines certain general features of the contract that must be publicly visible. A **Global State is always a public state**, and can be written in Genesis by the [contract issuer](/annexes/glossary#contract-participant) and later modified in state transition by a legitimate party defined in the contract schema.

The Global State is usually made available by contract issuers or contract participants and distributed through both centralized and decentralized public networks (e.g. websites, IPFS, Nostr, Torrent, etc.) in form of a [contract consignment](/annexes/glossary#consignment). It's important to note that the **availability** of the Global State is incentivized only by economic means of using and sharing the contract to the wider public: the parties involved are committed to bear the cost of the necessary storage solution that enables the accessibility of this kind of contract data.

Each component of a Global State consists of a 2-field structure that includes:

* A `GlobalType` which embeds a deterministic reference to the global propriety expressed in the [Schema](/rgb-contract-implementation/schema).
* The actual Data expressing the property.

For example, the Global State of a newly issued [Non Inflatable Asset](/rgb-contract-implementation/schema/non-inflatable-fungible-asset-schema), which is encoded in the Genesis, contains:

* The `ticker`.
* The full name of the token: `name`.
* The precision of decimal digits: `precision`.
* The issued supply of the token: `issuedSupply`.
* A text with some legal disclaimer: `terms`.

### Assignments

Assignments are the core constructs responsible for the [Seal Definition](/annexes/glossary#seal-definition) operation and related [Owned State](/annexes/glossary#owned-state) to which that Seal Definition is bound. They are the central part that enables the **rightful transfer of a digital property**, described in the Owned State, to a New Owner identified by the possession of a specific Bitcoin [UTXO](/annexes/glossary#utxo). An Assignment can be compared to a Bitcoin Transaction Output, but possibly embedding more expressiveness and potential.

Each Assignment consists of the following components:

* The `AssignmentType` which is the identifier of the digital property that is stored in the Assignment (e.g. `assetOwner`, which identifies a token allocation with its amount).
* The `Seal Definition` which is a sub-construct containing the reference to the UTXO.
* The `Owned State` which specifies how the properties associated with the `AssignmentType` are modified.

#### Seal Definition

The first main component of the Assignment construct is the [Seal Definition](https://github.com/rgb-protocol/rgb-consensus/blob/master/src/seals/txout/blind.rs) which points to the new owner of the allocation in the form of `txptr`, `vout` and `blinding`.

* `txptr` is a more complex object than a simple hash of a Bitcoin Transaction. In particular, it can have two distinct kinds:

  * `Txid`: a regular bitcoin transaction identifier
  * `WitnessTx`: "self", a special value that allows to reference the [witness transaction](/annexes/glossary#witness-transaction) for the current transfer. This is required because the anchor contributes to the txid, leading to a circular dependency

  The `WitnessTx` value only applies to operations that have a witness transaction, which is not always the case. So we have different names for seals depending on whether it's allowed:

  * `Genesis seal`, created by [Genesis](/annexes/glossary#genesis), always needs to point to an existing `txid` since there is no witness transaction.
  * `Graph seal`, in which both kinds are supported:
    * `Txid`, which leads to what we call a "blinded transfer"
    * `WitnessTx`, that results in a so-called "witness transfer". This is useful for instance in Lighting channel updates and when the recipient doesn't have any available UTXOs.
* `vout` is the transaction output number within the Transaction which `txptr` refers to. The `txptr` field together with `vout` field constitute an extension of the standard bitcoin *outpoint*.
* `blinding` is a random number of 8 bytes, which allows the seal data to be effectively hidden once they have been hashed, providing privacy to the recipient at least until the allocation is later spent again.

The `concealed` form of the Seal Definition is simply the SHA-256 [tagged hash](/annexes/commitments#specific-rgb-consensus-commitments) of the concatenation of the four fields:

`SHA-256(SHA-256(seal_tag) || SHA-256(seal_tag) || txptr || vout || blinding)`

Where:

* `seal_tag = urn:lnp-bp:seals:secret#2024-02-03`

```mermaid
---
title: Components of the Seal Definition
---
classDiagram
    direction LR
    BlindSeal ..|> SecretSeal : conceal
    class BlindSeal {
      txptr: Txid | WitnessTx
      vout: int
      blinding: bytes
    }
    class SecretSeal {
      hash: bytes
    }
```

*Notes:*

* A `BlindSeal` in which `TxPtr` is bound to be a `Txid` is called `GenesisSeal`
* A `BlindSeal` in which `TxPtr` can be either a `Txid` or the special value `WitnessTx` is called `GraphSeal`

#### Owned States

This second Assignment component is responsible for defining and storing the data assigned by the Seal Definition. Before proceeding with the features of Owned States, a brief digression about `Conceal/Reveal` feature of this construct is necessary. Unlike the Global State, Owned States come in two forms:

* **Public** Owned States: in which related data must always be kept and transferred in a revealed form by their owner recursively. For example, they may apply to some image files that must be bound to ownership, but are always publicly shown. This form can be described by the phrase: **"someone owns, everybody knows"**.
* **Private** Owned States: in which related data is kept hidden and revealed only if it is part of the history for validation purposes. For example, the number of tokens transferred in a token contract is generally kept private. This form can be summarized by the sentence: **"someone owns, nobody knows"**.

In RGB, an Owned State can only be defined with one of the three **StateTypes**: `Declarative`, `Fungible`, `Structured`:

* `Declarative` is a StateType with **no data**, representing some form of governance [rights](/annexes/glossary#contract-rights) that can be performed by a contract party. For example, it can be used for *voting rights*.
* `Fungible` is the StateType that allows for the transfer of **fungible units** such as those in a token contract; it consists of a single `amount` field.
* `Structured` is a State Type that can accommodate ordered and limited data collections of arbitrary content, which can be used as input for complex contract validation schemes. Its maximum storage size is limited to a maximum of 64 KiB.

The diagram below shows a summary of the three state types with their content:

{% code fullWidth="true" %}

```
  State                 Content

+---------------------------------------

                     +---------------+
                     |               |
  Declarative        |   < void >    |
                     |               |
                     +---------------+

+---------------------------------------

                     +---------------+
                     | +-----------+ |
  Fungible           | |   Amount  | |
                     | +-----------+ |
                     +---------------+

+-------------------------------------

                     +---------------+
                     | +-----------+ |
  Structured         | | Data Blob | |
                     | +-----------+ |
                     +---------------+
```

{% endcode %}

In addition, a summary of the technical characteristics of each **StateType** is provided in the table below:

<table><thead><tr><th width="164">Item</th><th width="136">Declarative</th><th width="132">Fungible</th><th>Structured</th></tr></thead><tbody><tr><td><strong>Data</strong></td><td>None</td><td>64-bit signed/unsigned integer</td><td>Any strict data type</td></tr><tr><td><strong>Type info</strong></td><td>None</td><td>Signed/unsigned</td><td>Strict Types</td></tr><tr><td><strong>Size limits</strong></td><td>N/A</td><td>256 Byte</td><td>Up to 64 kByte</td></tr></tbody></table>

## Inputs

Similar to Bitcoin Transactions, **Inputs represent the "other half" of the Assignment construct**. They have the basic role of referencing Assignments from a previous State Transition or Genesis. Inputs are not present in Genesis and consist of the following fields:

* `PrevOpId` containing the identifier of the previous Assignment operation being referenced.
* `AssignmentType` containing the identifier of the contract property being modified by the referenced Assignment.
* `Index` is the index number of the Assignment being referenced within the Assignment list of the `PrevOpId`. The `Index` is calculated implicitly from the lexicographic sorting of the hashes of the **Concealed Seal** of the referenced Assignments.

The validation procedure of RGB, in addition to checking the correct closure of the Seal, is also responsible for checking the consistency between the inputs and outputs, particularly for the `Fungible` StateType. In this case, the validation procedure, embedded in the [AluVM](/annexes/glossary#aluvm) script part of the [Schema](/annexes/glossary#schema), checks that the amount of tokens of each Input of a specific `AssignmentType` matches the number of tokens of the Assignments with the same `AssignmentType`.

As a natural property, Genesis has no Inputs as well as all State Transitions that don't change some Owned States of any kind. For example, a State Transition that changes only the Global State has no Inputs.

## Metadata

The metadata construct is a particular field that contains all the information that is not useful to be stored as part of the contract state history. It has a maximum size of 64 KiB and can be used, for example, to host temporary data from a complex contract validation procedure by the AluVm engine.

***


# Features of RGB State

## Strict Type System

As described in the previous sections, the [state](/annexes/glossary#contract-state) represents a set of conditions that are subjected to validation against both the [business logic](/annexes/glossary#business-logic) and ordered history of commitments.

In RGB, this set of data is actually an **arbitrary rich set of data** which:

* Are **strongly typed**, meaning that **each variable has a clear type definition (e.g. u8) and lower and upper bounds.**
* Can be **nested**, meaning that a type can be constructed from other types.
* Can be organized in `lists`, `sets` or `maps`.

To properly encode data in the state in a reproducible way, a [Strict Type System](/annexes/rgb-library-map#strict-types) has been adopted in RGB. This means that:

* Encoding of the data is done following some [Schema](/annexes/glossary#schema) structure which, unlike JSON or YAML, defines a precise layout of the data, thus also allowing deterministic ordering of each data element.
* The ordering of elements within each collection (i.e., in lists, sets or maps) is also deterministic.
* Bounds (lower and upper) are defined for each variable or data structure. This property is also applied to the number of elements in each collection (the so called **Confinement**).
* All data fields are byte-aligned.
* Data serialization and hashing are performed deterministically (Strict Encoding), allowing **reproducible commitments** of the data to be created regardless of the system on which that operation is performed.
* Data creation according to the schema is **performed through a simple description language which compiles to binary form** from the Rust Language. Extension to other languages will be supported in the future.
* In addition, compilation according to the Strict Type System produces two types of output:
  * A **compile-time Memory Layout**.
  * **Semantic identifiers** associated with memory layout (i.e., the commitment to the name of each data field). For instance, this type of construction is able to make detectable the change of a single variable name, which **doesn't change the memory layout** but **changes the semantics**.
* Finally, Strict Type System allows for **versioning** of the compilation schema, thus enabling the tracking of consensus changes in contracts and the compilation engine. To this end each compilation of an RGB object, being it a Schema or RGB libraries themselves, produces an **unique fingerprint** such as:

`RWhwUfTMpuP2Zfx1~j4nswCANGeJrYOqDcKelaMV4zU#remote-digital-pegasus`

As a matter of fact, Strict Encoding is defined both at an extremely pure functional level (thus far away from object-oriented programming (OOP) philosophy) and at a very low level (almost a hardware definition, thus far removed from more abstract structures and languages).

### Size limitation of validated data

Regarding **data participating in state validation**, the RGB protocol consensus rule applies a **maximum size limit** of 2^16 bytes (64 KiB):

* To the size of **any type of data** participating in state validation (e.g. a maximum of 65536 x `u8`, 32768 x `u16`, etc...)
* To the **number of elements of each collection** employed in state validation. This is designed to:
  * Avoid unlimited growth of client-side validated data per each state transition.
  * Ensure that this size fits the register size of a particular virtual machine [AluVM](/rgb-state-and-operations/state-transitions) that is capable of performing complex validations along with RGB.

## The Validation != Ownership Paradigm in RGB

One of the most important features of RGB compared to most blockchain-based smart contract systems is based on the **clear separation between the validation task and ownership** that are defined by the protocol at the most fundamental level.

![](/files/ISHbdpD4n8My29M3HcBm)

In practice:

* The **Validation** task, performed by users and observers of the protocol, ensures **how the properties of a smart contract can change** and thus the internal consistency and adherence of state transitions to the smart contract rule. This process is fully realized by the stratification of the stack of [RGB-specific](/annexes/rgb-library-map) libraries.
* The **Ownership** property, which, through the definition of the seal pointing to a Bitcoin UTXO, **defines who can change the state**. The security level of this property depends entirely on the security model of Bitcoin itself.

This type of separation **prevents the possibility of mixing the non-Turing complete capabilities of smart contracts with the public access to contract states** that is embedded in almost all blockchains with advanced programming capabilities. In contrast, **the use of these common "mixed" architectures has led to frequent and notable hacks** in which yet unknown vulnerabilities of smart contracts have been exploited by publicly accessing the contract state encoded in the blockchain.

Moreover, based on Bitcoin's transaction structure, RGB can exploit the **features of the Lightning Network** directly.

## RGB Consensus Changes

As another important feature, RGB has, in addition to Semantic Versioning of data, a **Consensus Update System**, which tracks changes in consent in [contracts](/annexes/glossary#contract) and [contract operations](/annexes/glossary#contract-operation).

There are basically two ways to update the consent rule embedded in the protocol.

### **Fast-forward**

A **fast-forward** update occurs when *some previously invalid rule becomes valid*. Despite the similarities, this kind of update is **NOT comparable to a blockchain hardfork**. The chronological history of this kind of changes is mapped into the contract through the [Ffv field](#components-of-a-contract-operation) of Contract Operation. Specifically, it is characterized by the following properties:

* Existing owners are not affected.
* New beneficiaries must upgrade their wallets.

### Push-back

A **push-back** update occurs when *some previously valid state becomes invalid*. Despite the similarities, this kind of update is **NOT comparable to a blockchain softfork**, and furthermore:

* Existing owners can lose assets if they update their wallets.
* It's actually a new protocol, no longer the same version of RGB.
* Can only occur through issuers reissuing assets on a new protocol and users using two wallets (for both the old and new protocols).


# Schema

An RGB Schema represents a template that can be used to issue contracts having a common structure, embedding the rules of [contract operations](/annexes/glossary#contract-operation) representing its [business logic](/annexes/glossary#business-logic) and thus describing how its [state](/annexes/glossary#contract-state) can be updated. Each contract implementing a schema assigns concrete values to contract fields in its Genesis, defining global state and initial owners for the newly created owned state.

An RGB Schema is the analog of a class for an OOP language. Hence such a construction is used to define the various standards for RGB contracts and assets, for example: fungible assets, collectibles, digital identities, etc.

The [issuer](/annexes/glossary#contract-participant) of an asset on RGB uses (and makes available to the public) a Schema in order to define the issuance properties encoded in the Genesis. This way, the contract can be supported by RGB wallets and become fully operational. Thus, **when the users receive some information about an asset on RGB (data and contract) they must validate them against the Schema distributed by the issuer of that asset.**

In fact, the Schema validation is the very first operation step that a user needs to undergo before interacting in any way with the contract (e.g. to perform the desired contract operations).

From a functional point of view, the **Schema construct addresses the following questions**:

* What kinds of owned states and [Assignments](/annexes/glossary#assignment) exist?
* What [Global State](/rgb-state-and-operations/components-of-a-contract-operation#global-state) does the contract have?
* How is [Genesis](/annexes/glossary#genesis) structured?
* What kind of [State Transitions](/annexes/glossary#state-transition) are possible?
* What [Metadata](/rgb-state-and-operations/components-of-a-contract-operation#metadata) can contract operations have?
* How state data are allowed to change within state transitions?
* What sequences of transitions are allowed?

<figure><img src="/files/qWpEI1E6rLiJaOPHKUDq" alt=""><figcaption><p><strong>Elements contained in an RGB Schema</strong></p></figcaption></figure>

**From a technical point of view, an RGB Schema is a functional declarative document that need to be compiled for effective usage inside RGB applications and wallets.**

Among the most important properties, a Schema:

* Defines all the variables used in contract state and transitions using a specific [strict type system](/annexes/glossary#strict-type-system) encoding. Such variables, depending on their scope, may be of different types:
  * Metadata: related to a single operation
  * Owned state: created by an operation and consumed by a second one
  * Global state: created by an operation, which it shares the visibility of
* Defines all the data structures required for Genesis operation, which represents the first instantiation of the contract.
* Defines a list of supported contract Transitions; for each of them:
  * Describes what data types it works with: owned state in input/output and global state/metadata it optionally defines
  * Embeds the **state validation script** and the related functions for the client-side part of RGB. The scripts, which executed through the [AluVM](/annexes/glossary#aluvm) engine, represent the most fundamental component of the business logic.

**Schema architecture appears to be very different from blockchain-based contracts**, for example those implemented on Ethereum. Indeed, in these systems **the contract itself is provided as executable code** that defines the rules for changing and implementing the state which is eventually directly stored into the blockchain. **In contrast, in RGB the contract is encoded in a purely declarative way.**

In every Contract Operation performed in the client-side validation phase, the Contract Schema is always referenced and checked against. In particular, after compilation, the Schema can provide all the necessary data structure to perform the issuance of the contract represented by the Genesis Operation.

As [mentioned earlier](/rgb-state-and-operations/features-of-rgb-state#the-validation-ownership-paradigm-in-rgb), **Schema clearly differentiates contract developers from issuers**, who may know nothing about coding and programming. This kind of approach makes extensive use of **contract templates** which can be used promptly by issuers who may benefit from avoiding common programming mistakes in the implementation phase.

After compilation, the Schema is encoded in a `.rgb` binary file or in an `.rgba` armored binary file, which can be imported by the wallet software.

An issuer will then create a particular instance of a schema by filling it in with data such as `precision`, `name` and `issuedSupply`. Initial allocations are also defined, and the resulting structure is encoded into a consignment file and shared with the new owners. Once the first state transition happens, the contract will (indirectly) be committed onchain and take full effect.

In the next chapter, we provide a list of currently supported schemas.


# Supported schemas

This section lists the schemas that have been officially implemented so far, describing the data they work with and the list of supported operations.

## NIA (Non Inflatable Asset)

This schema defines a non-inflatable fungible asset, involving the following data:

* AssetSpec: groups basic asset information, namely:
  * Ticker: short identifier of the asset, to be displayed on wallets and exchanges (e.g.: BTC, USDT, ...). Note that there is no guarantee of uniqueness
  * Name: extended name of the asset (e.g.: Bitcoin, Tether, ...)
  * Details: optional string describing the asset in more detail
  * Precision: Number of decimal places of the standard representation of the asset (e.g. would be 8 for BTC and 2 for USD)
* Contract Terms: contains a string describing the contract and an optional media attachment
* Issued Supply: total amount of tokens created at issuance. Since the asset is not inflatable, it also serves as an upper bound on the circulating supply

The following operations are supported for the asset:

* Transfer: send some amount of assets to a number of destinations (optionally including change); it supports multiple inputs in case multiple allocations should be merged in order to build up the desired output amount

## UDA (Unique Digital Asset)

This schema defines a unique non-fungible asset (NFT), involving the following data:

* AssetSpec: groups basic asset information, namely:
  * Ticker: short identifier of the asset, to be displayed on wallets and exchanges. Note that there is no guarantee of uniqueness
  * Name: extended name of the asset
  * Details: optional string describing the asset in more detail
  * Precision: Number of decimal places of the standard representation of the asset
* Contract Terms: contains a string describing the contract and an optional media attachment
* EmbeddedMedia: a media type associated with a binary blob (max. \~64KiB), can be used to embed some media (e.g. a small image) into the contract
* Attachments: a list of media types associated with a hash digest, can be used to attach some large media (e.g. videos or HD images), without including them in the contract as a whole. The data itself should be made available by other means, while its digest can be checked against the one in the contract
* ProofOfReserves: a bitcoin outpoint paired with a binary proof, can be used to show that some tokens are locked as a reserve for the UDA asset

The following operations are supported for the asset:

* Transfer: send the assets to a destination.

## CFA (Collectible Fungible Asset)

This schema defines a collectible fungible asset. It is similar to NIA, with an additional string (Article) that represents the collectible.

The following operations are supported for the asset:

* Transfer: send some amount of assets to a number of destinations (optionally including change); it supports multiple inputs in case multiple allocations should be merged in order to build up the desired output amount.

## IFA (Inflatable Fungible Asset)

This schema defines an inflatable fungible asset, involving the following data:

* AssetSpec: groups basic asset information, namely:
  * Ticker: short identifier of the asset, to be displayed on wallets and exchanges (e.g.: BTC, USDT, ...). Note that there is no guarantee of uniqueness
  * Name: extended name of the asset (e.g.: Bitcoin, Tether, ...)
  * Details: optional string describing the asset in more detail
  * Precision: Number of decimal places of the standard representation of the asset (e.g. would be 8 for BTC and 2 for USD)
* Contract Terms: contains a string describing the contract and an optional media attachment
* Issued Supply: amount of issued tokens in a certain operation, which can be either Genesis or an Inflation Transition. It represents the amount of the initial issuance and of each secondary issuance, respectively
* Total Supply: the sum of the issued supply and the allowed inflation amount. It serves as an upper bound on the circulating supply, which can be more closely estimated through other means
* RejectListUrl: an optional URL where the issuer can provide a list of operations that should be considered invalid. This cannot be enforced by the issuer due to the nature of client side validation, and wallets are free to ignore it
* LinkedFromContract, LinkedToContract: optional `ContractId`s that should be considered equivalent economic objects as the current asset, may be used by the issuer to update an asset to a different schema or a different version of the IFA schema. The contract link from `A` to `B` should only be considered valid if `A.LinkedToContract` is `B` AND `B.LinkedFromContract` is `A`; this guarantees that the issuers of both assets are willing to consider them the same economic structure

Additionally to the owned state representing the asset's allocation, an IFA asset can optionally define rights:

* Inflation: allows its owner to inflate the asset by a certain amount, using this right will reduce the remaining inflatable amount
* Link: allows its owner to link the current asset to another one, by setting a value to the `LinkedToContract` global state

The following operations are supported for the asset:

* Transfer: send some amount of assets to a number of destinations (optionally including change); it supports multiple inputs in case multiple allocations should be merged in order to build up the desired output amount
* Inflate: use an inflation right to issue a certain amount of assets in circulation, which can be optionally split into more than one allocation. The remaining inflation right (if any) can also optionally be split into more than one allocation
* Burn: burn (asset or right) allocations by adding them as input to a burn transition. Fungible allocations can be burned partially by adding change outputs; the burned amount must be non-zero and must be declared in a metadata, which can be used as source of truth. Non-fungible allocations must be burned in full, so they have no output.

  This transition allows to prove to a third party that some right or a certain amount of assets no longer exists, e.g. as part of a protocol with wider scope
* Link: Link this asset to another linkable one. This operation can be done at most once in the life of a contract, hence the corresponding right is lost after this operation is performed

## PFA (Permissioned Fungible Asset)

This schema defines a permissioned, non-inflatable fungible asset, in which the issuer needs to explicitly authorize every transfer; e.g. it may be used to represent company shares, for which there are legal constraints on the potential owners. It involves the following data:

* AssetSpec: groups basic asset information, namely:
  * Ticker: short identifier of the asset, to be displayed on wallets and exchanges. Note that there is no guarantee of uniqueness
  * Name: extended name of the asset
  * Details: optional string describing the asset in more detail
  * Precision: Number of decimal places of the standard representation of the asset
* Contract Terms: contains a string describing the contract and an optional media attachment
* Issued Supply: total amount of tokens created at issuance. Since the asset is not inflatable, it also serves as an upper bound on the circulating supply
* Pubkey: public key identifying the entity that needs to sign every transfer

The following operations are supported for the asset:

* Transfer: send some amount of assets to a number of destinations (optionally including change); it supports multiple inputs in case multiple allocations should be merged in order to build up the desired output amount and it must have a metadata containing the issuer's signature, which is checked by the receiving wallet using the Pubkey in Genesis

***

In the next subsection, we will provide an example of an actual Schema used for the issuance of a **Non Inflatable Asset.**


# Schema example: Non-Inflatable Assets

In this section, we will look more closely at an actual example of an RGB Contract Schema written in Rust and contained in the [nia.rs](https://github.com/rgb-protocol/rgb-schemas/blob/master/src/nia.rs) file from the [RGB Schemas Repository](/annexes/rgb-library-map#rgb-schemas). The Repository contains an example set of schema templates related to other types of contracts. This Schema, which we will be using as an example in this chapter, allows for the contract setup of N**on-Inflatable Assets** **(NIA)** that can be considered as the RGB analog to Ethereum's fungible tokens created with the ERC20 standard.

We can observe that a Schema can be divided into several general sections:

* A *header* which contains:
  * An optional Root `SchemaId` which indicates a limited form of inheritance from some master schema.
  * A reserved `Feature` field which provides room for additional future extensions of contract schema.
* A first section in which all the **State Types** and related variables (both pertaining to [Global](/rgb-state-and-operations/components-of-a-contract-operation#global-state) and [Assignments](/rgb-state-and-operations/components-of-a-contract-operation#assignments)) are declared.
* A second section where all the possible [Contract Operations](/annexes/glossary#contract-operation) referencing the previously declared State Types are encoded.
* A field containing the declaration of the **Strict Type System** being used in the whole schema.
* A last section containing the **validation scripts** for all the operations.

After this layout indication, we provide below the actual Rust Code of the schema. Each code section is provided with a numbered reference to an explanation paragraph reported below.

{% code fullWidth="true" %}

```rust
fn nia_schema() -> Schema { 

    // definitions of libraries and variables

    Schema {
        ffv: zero!(),                                                                            // --+
        name: tn!("NonInflatableAsset"),                                                         //   |  (1)
        meta_types: none!(),                                                                     // --+
        global_types: tiny_bmap! {                                                                       // --+
            GS_NOMINAL => GlobalDetails {                                                                //   |
                global_state_schema: GlobalStateSchema::once(types.get("RGBContract.AssetSpec")),        //   |
                name: fname!("spec"),                                                                    //   |
            },                                                                                           //   |
            GS_TERMS => GlobalDetails {                                                                  //   |
                global_state_schema: GlobalStateSchema::once(types.get("RGBContract.ContractTerms")),    //   |  (2)
                name: fname!("terms"),                                                                   //   |
            },                                                                                           //   |
            GS_ISSUED_SUPPLY => GlobalDetails {                                                          //   |
                global_state_schema: GlobalStateSchema::once(types.get("RGBContract.Amount")),           //   |
                name: fname!("issuedSupply"),                                                            //   |
            },                                                                                           //   |
        },                                                                                               // --+
        owned_types: tiny_bmap! {                                                             // --+
            OS_ASSET => AssignmentDetails {                                                   //   |
                owned_state_schema: OwnedStateSchema::Fungible(FungibleType::Unsigned64Bit),  //   |
                name: fname!("assetOwner"),                                                   //   |  (3)
                default_transition: TS_TRANSFER,                                              //   |
            }                                                                                 //   |
        },                                                                                    // --+
        genesis: GenesisSchema {                                                 //  --+ -------> Contract declaration start here
            metadata: none!(),                                                   //    |
            globals: tiny_bmap! {                                                //    |
                GS_NOMINAL => Occurrences::Once,                                 //    |
                GS_TERMS => Occurrences::Once,                                   //    |
                GS_ISSUED_SUPPLY => Occurrences::Once,                           //    |
            },                                                                   //    |   (4)
            assignments: tiny_bmap! {                                            //    |
                OS_ASSET => Occurrences::OnceOrMore,                             //    |
            },                                                                   //    |
            validator: Some(LibSite::with(FN_NIA_GENESIS_OFFSET, alu_id)),       //    |
        },                                                                       //  --+
        transitions: tiny_bmap! {
            TS_TRANSFER => TransitionDetails {                                   //  --+
                transition_schema: TransitionSchema {                            //    |
                    metadata: none!(),                                           //    |
                    globals: none!(),                                            //    |
                    inputs: tiny_bmap! {                                         //    |
                        OS_ASSET => Occurrences::OnceOrMore                      //    |
                    },                                                           //    |   (5)
                    assignments: tiny_bmap! {                                    //    |
                        OS_ASSET => Occurrences::OnceOrMore                      //    |
                    },                                                           //    |
                    validator: Some(LibSite::with(FN_NIA_TRANSFER_OFFSET, alu_id)//    |
                },                                                               //    |
                name: fname!("transfer"),                                        //    |
            }                                                                    //  --+
        },
        default_assignment: Some(OS_ASSET),               //  --+ (6)
    }
}
```

{% endcode %}

**(1)** In this section:

* `ffv` statement indicates the version of the contract.
* `name` provides a human-readable identifier for the schema itself, although it provides no uniqueness guarantees

**(2)** In this section `global_state` and its variables are declared, in particular:

* The token's `GS_NOMINAL` set of specifications which according to the [Strict Type Library](/annexes/rgb-library-map#strict-types) contain: the token full `name` , the `ticker`, some additional `details`, the digit `precision` of the asset.
* `GS_TERMS` containing some additional contract `terms` such as a disclaimer.
* `GS_ISSUED_SUPPLY` which defines the initial supply of the token. In this case, since no inflation is allowed, it also represents the max supply.
* The `Once` statement guarantees that all these declarations are associated with a single value.

**(3)** In `owned_type` section, through the `OS_ASSET` statement, we can find the **StateType declaration** of the fungible token being transferred through the owned state assignment. The quantity of token used in the transfer is declared as a [Fungible Type](/rgb-state-and-operations/components-of-a-contract-operation#owned-states) represented by a 64-bit unsigned integer. Additionally, we provide each assignment type with a default transition, which allows for instance to move it automatically to another seal when spending other allocations on the same UTXO.

**(4)** This section of the contract schema marks the beginning of **Contract Operations' declaration section.** Starting from the operation allowed within `genesis` :

* No `metadata` are declared.
* The instantiation, inside the Genesis state, of all the variables of the Global State variables previously defined in code section (2).
* The declaration of the first `assignment(s)` of the token using the previously declared type `OS_ASSET`. Note that the `OnceOrMore` statement allows more than one allocation, in case the issuer wants to split the initial supply among multiple owners.

**(5)** The `transitions` section provides the declaration of a single `TS_TRANSFER` operation which:

* Contains no `metadata`.
* Doesn't update the global state (it was defined only in Genesis).
* Takes as `inputs` at **one or more** assignments of type `OS_ASSET`.
* Allows to declare **one or more** `assignments` of type `OS_ASSET`.
* Points to the `AluVM` script that should be **executed when validating** operations of this type.

**(6)** A **default assignment type** is defined, to be used for example to pay an invoice that doesn't specify one.


# Lightning Network compatibility

When an RGB state transition is committed into a Bitcoin transaction, such transaction does not necessarily need to be settled on the blockchain immediately, as it can derive its security by being part of a [Lightning Network](/annexes/glossary#lightning-network) payment channel. In this way, every time the Lightning channel is updated, a new RGB state transition can be committed inside the new channel update transaction, invalidating the previous one. It is therefore possible to have lightning channels that move RGB assets, and to route payments across channels, just like with regular lightning payments.

The first thing needed for an RGB lightning channel to work is a funding transaction. The funding operation is composed of two parts:

1. The bitcoin funding to create the multisig.
2. The RGB asset funding sending assets to the multisig [UTXO](/annexes/glossary#utxo).

The bitcoin funding is needed to create the channel UTXO where the assets can be allocated to, but it doesn’t necessarily need to have an economically significant amount of satoshis in it as long as it has enough balance that all the outputs of the lightning commitment transitions will be above the dust limit.

<figure><img src="/files/IQ7XRmHuo6FxHYHypVQ7" alt=""><figcaption><p><strong>In this example Alice is opening a channel with Bob providing 10k satoshis and 500 USDT. Here the RGB commitment is added in a dedicated OP_RETURN output, but it could also be a Taproot output as RGB support both as a commitment scheme.</strong></p></figcaption></figure>

Once the funding transaction has been prepared, but not yet signed and broadcast, it is time to prepare the commitment transactions that will allow both parties to unilaterally close the channel at any time. The structure of the commitment transactions are almost identical to those of normal lightning channels, with the only difference being that an extra output is added to contain the RGB anchor to the RGB state transition, which in this example uses the OP\_RETURN commitment scheme, but when Taproot payment channels will be available the Taproot commitment scheme can be used as well.

<figure><img src="/files/fODLDwfGLIen2SCKchwz" alt=""><figcaption><p><strong>Commitment transaction signed by Alice and ready to be broadcasted by Bob, with associated RGB state transition.</strong></p></figcaption></figure>

<figure><img src="/files/06rtvF6G9CbqRGb9lxw7" alt=""><figcaption><p><strong>Commitment transaction signed by Bob and ready to be broadcast by Alice, with associated RGB state transition.</strong></p></figcaption></figure>

As we can see in the example, the RGB state transition is moving the assets towards the allocation that corresponds to the output created by the lightning commitment transaction. This means that Alice, if Bob were to become irresponsive until the timelock expired, would be able to recover both satoshis and USDTs she locked in the channel.

## Updating the channel

When a payment occurs between the two parties and the state of the channel needs to be updated, a new pair of commitment transactions will be created. The bitcoin amounts in the output of the new commitment transaction are not relevant and may or may not stay the same as they were in a previous state (depending on the implementation), as their primary scope is to enable the creation of a new UTXO, not the movement of economic value denominated in bitcoin. However, the OP\_RETURN (or in the future Taproot) output needs to change as now it will have to contain the RGB anchor to a new RGB state transition, which, differently from the previous one, will update the asset amounts reflecting the new balances after the payment happened.

In the example below, 100 USDT have been moved from Alice to Bob, making the new state of the balances be 400 USDT to Alice and 100 USDT to Bob.

<figure><img src="/files/47zYinP41UHFWbKEnvHl" alt=""><figcaption><p><strong>Update to the commitment transaction, signed by Alice and ready to be broadcasted by Bob.</strong></p></figcaption></figure>

<figure><img src="/files/QNYJfqMhjuBGO8DZP5gt" alt=""><figcaption><p><strong>Update to the commitment transaction, signed by Bob and ready to be broadcasted by Alice.</strong></p></figcaption></figure>

Notice that in the RGB state transition, while the UTXO endpoints where the assets get allocated change with every new lightning commitment transaction, the RGB input is always the original funding multisig where the assets are allocated on-chain until the channel closure.

The RGB state transition moves the assets from the multisig where the funding happened, towards the outputs that are being created by the lightning commitment transaction. In this way, the RGB state transition inherits directly from the lightning commitment transaction all the security properties in case of unilateral channel closing. Moreover, after commitments are exchanged, Alice and Bob share the revocation secrets of the previous channel state, invalidating it in favor of the new state.

This means that if Alice broadcasts an old state (trying to get back the 100 USDT she just sent), Bob will be able to spend the output using Alice’s revocation secret, and while spending the output he will not only move the satoshis towards an address under his exclusive control, but he will also be able to move the RGB assets towards himslf. In this way, the economic punishment for trying to steal with an old state does not come only from the satoshis amount (which may be insignificant), but also from all the RGB assets that were locked in the channel. On the contrary, if the commitment transaction broadcast by Bob was indeed the last state of the channel, Bob won’t be able to spend the output triggering the punishment transaction, and Alice will be able to take both the satoshis and the RGB assets after the timelock has expired.

## Introducing HTLCs

Above we just saw a simplification of payment channels that involve only two parties, but since in reality the lightning network is designed also to route payments towards more participants, all payments actually use HTLCs output. With RGB channels it works exactly the same way, for each payment that is being routed through the channels, a dedicated HTLC output will be added to the lightning commitment transaction. The HTLC output needs to have a bitcoin amount higher than the dust limit, but it can remain economically insignificant. Together with the new HTLC output, a new allocation needs to be added to the RGB state transition, which will send the amount of assets involved in the payment towards the new HTLC output. Whoever manages to spend the HTLC output, either through knowledge of a secret or by waiting for a timelock expiration, will be able to move both the satoshis that were in the output, and all the assets assigned to it.

<figure><img src="/files/ClAPAdVzj0qXaCItHUOP" alt=""><figcaption><p><strong>HTLC transaction involving RGB state transition.</strong></p></figcaption></figure>

The above example only contains one HTLC output, but more can be added as needed for all the pending routed payments, and for each new HTLC output there will be a new corresponding RGB allocation in the state transition.

Every HTLC output needs a bitcoin amount above dust that ensures, in case the channel is force-closed while the payment is in flight, the legitimate owner will be able to spend it and claim the corresponding assets. This means that, in practice, every RGB payment on lightning also needs to transfer some satoshis as well.


# Glossary

Terminology used in RGB sorted in alphabetical order

### Anchor

Set of client-side data that proves the inclusion of a unique [commitment](#commitment) inside a transaction. In RGB protocol it is constituted by:

* The Bitcoin transaction ID of the [witness transaction](#witness-transaction).
* The Multi Protocol Commitment - [MPC](#multi-protocol-commitment-mpc).
* The Deterministic Bitcoin Commitment - [DBC](#deterministic-bitcoin-commitment-dbc).
* The [ETP](#extra-transaction-proof-etp) in the case of [Tapret](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret) commitment scheme.

### AluVM

Acronym of Algorithmic logic unit Virtual Machine, it is a register-based virtual machine for smart contract validation and distributed computing, used but not limited to RGB contract validation.

[Link](/annexes/rgb-library-map#aluvm).

### Assignment

The RGB-equivalent of a transaction output modifying, updating or creating some properties of the state of a [contract](#contract). It is formed by:

* A [Seal Definition](#seal-definition)
* An [Owned State](/rgb-state-and-operations/components-of-a-contract-operation#owned-states)

[Link](/rgb-state-and-operations/components-of-a-contract-operation#assignments-of-an-owned-state)

### Business Logic

The set of operations and rules contained in a contract [Schema](#schema) which allows for the rightful update of the [contract state](#contract-state).

### Client-side Validation

The operation which allows the verification of some data exchanged between parties according to some defined protocol rules. In RGB protocol these data are in form of [consignment](#consignment); the above data can be exchanged privately between the parties involved as, unlike Bitcoin protocol, they don't need to be registered on a public medium (e.g. the blockchain).

### Commitment

A defined mathematical object $$C$$, deterministically derived from applying a cryptographic operation to some structured input data $$m$$, called the message. The commitment can be registered in a defined publication medium (e.g. the blockchain) and embeds two operations:

* ***Commit** operation, which* takes as inputs a public message $$m$$ and a random value $$r$$, and by applying to them the chosen cryptographic algorithm returns a value $$C = \text{commit}(m, r)$$.
* ***Verify** operation, which* takes the value returned by the commit algorithm $$C$$, the public message $$m$$ and the secret value $$r$$ and returns True/False. $$\text{verify}(m, r, com) \rightarrow (\text{True} / \text{False})$$.

The commitment is required to possess two fundamental security properties:

* ***Binding***: requires that there cannot be two valid messages of the same commitment $$C$$. That is, it is computationally unfeasible to produce different $$m' : | : m' \neq m$$ and $$r' : | : r' \neq r$$ such that: $$\text{verify}(m,r,C)=\text{verify}(m',r',C) \rightarrow \text{True}$$
* ***Hiding***: requires that the message $$m$$ cannot be easily discovered by commitment attempts, i.e., that $$r$$ be uniformly sampled in a set $$R$$ such that it is statistically independent of $$m$$.

### Consignment

The data transferred between parties that are subject to [client-side validation](#client-side-validation). In RGB there are 2 types of consignment:

* **Contract Consignment**: provided by the contract issuer, includes the information about the contract setup, such as the [Schema](#schema) and the [Genesis](#genesis).
* **Transfer Consignment**: provided by the payer to the payee, contains all the state transition history from [Genesis](#genesis) to the newly created unspent [Assignments](#assignment).

### Contract

A set of [rights](#contract-rights) established and executed digitally between certain parties through RGB protocol. A contract possesses an [active state](/rgb-state-and-operations/state-transitions#state-generation-and-active-state) and [business logic](#business-logic), expressed in terms of ownership rights and executive rights. The contract state, rights and conditions of valid operations are defined using RGB [schema](#schema). Only state and operations which allowed by the schema declarations and validation scripts are allowed to happen within the contract scope.

### Contract Operation

An update to the [contract state](#contract-state) performed according to the rules defined in the contract [schema](#schema).

Contract operations include:

* [Genesis](#genesis)
* [State Transition](#state-transition)

### Contract Participant

An actor who participates in contract operations. Contract parties are classified into the following categories:

* **Contract issuer**: an actor creating contract [Genesis](#genesis).
* **Contract party**: all actors who have some [ownership](#ownership) rights over RGB [contract state](#contract-state) which have been provided through an [Assignment](#assignment).

### Contract Rights

RGB contract parties have different rights as a part of the contract conditions defined through RGB [Schema](#schema). The rights under RGB contracts can be classified into the following categories:

* Ownership rights: the rights associated with the [ownership](#ownership) of some UTXO referenced by a [Seal Definition](#seal-definition).
* Executive rights: the ability to construct the [contract state](#contract-state) in a final form, i.e. to construct a valid [state transition](#state-transition) satisfying [schema](#schema) validation rules.

### Contract State

The set of up-to-date, private, and public information that manifests the condition of a contract at a certain point in history. In RGB, the contract state is constituted by:

* [Global State](/rgb-state-and-operations/components-of-a-contract-operation#global-state)
* [Owned State(s)](/rgb-state-and-operations/components-of-a-contract-operation#owned-states)

### Deterministic Bitcoin Commitment - DBC

The set of rules which allows for the registration of a provably single [commitment](#commitment) in a Bitcoin transaction. Specifically, RGB protocol embeds 2 forms of DBC:

* [Opret](/commitment-layer/deterministic-bitcoin-commitments-dbc/opret)
* [Tapret](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret)

### Directed Acyclic Graph - DAG

A directed graph that does not contain any directed cycle thus allowing topological ordering. A Blockchain or an RGB Contract [Shard](#shard) are examples of DAG.

[Wikipedia link](https://en.wikipedia.org/wiki/Directed_acyclic_graph)

### Extra Transaction Proof - ETP

The part of the [Anchor](/commitment-layer/anchors) that embeds the additional data necessary for the validation of [Tapret](/commitment-layer/deterministic-bitcoin-commitments-dbc/tapret) commitment contained in a [taproot](#taproot) transaction, such as the internal PubKey and the Script Path Spend.

### Genesis

The set of data, regulated by a contract [schema](#schema), which represents the starting state of every contract of RGB. It's the equivalent of Bitcoin Genesis Block at the client-side level.

[Link](/rgb-state-and-operations/state-transitions#genesis)

### Invoice

A [base58](https://en.wikipedia.org/wiki/Binary-to-text_encoding#Base58) URL-encoded string embedding the necessary data in order to allow a payer counterpart to construct a [State Transition](#state-transition).

### Global State

The set of public properties included in the [state](#contract-state) of a [contract](#contract), defined in [Genesis](#genesis) and optionally updatable according to the rule defined therein, which are not [owned](#ownership) by any party.

[Link](/rgb-state-and-operations/components-of-a-contract-operation#global-state)

### Lightning Network

A decentralized network of bidirectional payment (state) channels constituted by 2-of-2 mutisig wallet constructing and updating off-chain transactions. It represents a popular Bitcoin Layer 2 scaling solution.

[Link](https://lightning.network/)

### Merkle Tree

A cryptographic data structure that allows small (logarithmic) inclusion proofs. It's composed of a binary tree in which leaves are the set elements, each intermediate node contains the hash of its children and the root commits to the whole set of elements. To prove a leaf is part of the tree it's enough to provide sibling hashes throughout the path from the leaf to the root, whose size grows logarithmically with the number of leaves.

[More details](https://developer.bitcoin.org/reference/block_chain.html#merkle-trees)

### Multi Protocol Commitment - MPC

The [Merkle Tree](#merkle-tree) structure used in RGB to include in a single Bitcoin Blockchain commitment the multiple [Transition Bundles](#transition-bundle) of different contracts.

[Link](/commitment-layer/multi-protocol-commitments-mpc)

### Owned State

Part of the [state](#contract-state) of a [contract](#contract) enclosed into an [Assignment](#assignment) that contains the definition of the digital property being subjected to someone's [ownership](#ownership).

[Link](/rgb-state-and-operations/components-of-a-contract-operation#owned-states)

### Ownership

The control and thus the possibility to spend a [UTXO](#utxo) to which some client-side property isthat [assigned](#assignment).

### Partially Signed Bitcoin Transaction - PSBT

A transaction which lacks some element of its signature and which can be completed/finalized with some additional elements later in time.

[Link](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)

### Schema

A declarative piece of code that contains the set of variables, rules, and [business logic](#business-logic) according to which an RGB contract works.

[Link](/rgb-contract-implementation/schema)

### Seal Definition

The reference part of an [Assignment](#assignment) which binds the commitment to a [UTXO](#utxo) belonging to the new [owner](#ownership).

[Link](/rgb-state-and-operations/components-of-a-contract-operation#seal-definition)

### Shard

A branch of the [DAG](#directed-acyclic-graph---dag) chain of the RGB [State Transitions](#state-transition).

### Single-Use Seal

A promise to [commit](#commitment) to a yet unknown message in the future, once and only once, such that commitment fact will be provably known to all members of a certain audience.

[Link](/distributed-computing-concepts/single-use-seals)

### Stash

The set of client-side data related to one or more [contracts](#contract) that undergo [validation](#client-side-validation) and are stored by the users.

### State Transition

The most important [contract operation](#contract-operation) that makes possible the transition of an RGB State to a New State, changing [state](#contract-state) data and/or ownership.

[Link](/rgb-state-and-operations/state-transitions#state-transitions-and-their-mechanics)

### Strict Type System

An infrastructure that allows to create complex types which are deterministically identified by their `semId`. It is used by schemas to precisely define the data type for their state.

[Link](/annexes/rgb-library-map#strict-types).

### Taproot

The Bitcoin's Segwit v1 transaction format detailed in [BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) and [BIP342](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki).

### Transition Bundle

A set of RGB [State Transitions](#state-transition) that belong to the same contract and that are committed in the same [witness transaction](#witness-transaction).

[Link](/rgb-state-and-operations/state-transitions#transition-bundle)

### UTXO

A Bitcoin Unspent Transaction Output. It is defined by a transaction hash and a *vout* index which, collectively, constitute an [outpoint](https://en.bitcoin.it/wiki/Protocol_documentation#tx).

### Witness Transaction

The transaction that provides the [Seal](#single-use-seal) closing operation around a message that contains a [Multi Protocol Commitment](#multi-protocol-commitment-mpc) an [MPC](#multi-protocol-commitment-mpc) Tree.

***


# Contract Transfers

In this section we will be guided through a step-by-step RGB Contract Transfer operation, again with the cooperation of our cryptographic couple: Alice and Bob. We will also provide some coding sections of both our characters, which use the `rgb` Command Line Interface Tool which can be installed from the dedicated [RGB library](/annexes/rgb-library-map#rgb-api-and-cli).

Let's start with Bob, who owns a Bitcoin wallet but has not yet started using RGB technology.

**1)** To begin operating with RGB protocol, **Bob must install an RGB wallet**. This startup process involves installing the RGB wallet software, which usually, by default, contains no contracts. The RGB wallet software, in addition, requires the ability to interact with Bitcoin UTXO through a Bitcoin wallet and a Bitcoin Blockchain node tool (a full node or an [Electrum Server](https://thebitcoinmanual.com/articles/btc-electrum-server/)). These tools are a mandatory requirement because, as we learned [previously](/rgb-state-and-operations/state-transitions#state-transitions-and-their-mechanics), [owned states](/annexes/glossary#owned-state) are defined over Bitcoin UTXO and represent a necessary item for [state transitions](/annexes/glossary#state-transition) implementing transfers of contract in RGB.

**2)** Then, Bob has the task of acquiring the **necessary information about the contracts.** These data, in the RGB ecosystem, can be sourced through various channels, such as specific websites, e-mails, or Telegram messages, etc, following the [contract issuer](/annexes/glossary#contract-participant)'s choice. These data are distributed using a [contract consignment ](/annexes/glossary#consignment)which is a data package containing [Genesis](/annexes/glossary#genesis) and [Schema](/annexes/glossary#schema).

Each of these parts, usually, consists of as little as 200 bytes of data, meaning **a consignment is typically of the order of a few KiBs**. The contract consignment can also be encoded in Base58 format and sent in a format similar to that of a PGP key or as a QR code. This kind of format In the future will also be easily adaptable to censorship-resistant transmission media such as **Nostr**, through the use of relay servers, or over the Lightning Network.

In this regards, it's useful to point out that the RGB ecosystem fosters innovation and competition among various wallets by allowing the freedom to propose new methods of contract interaction and transfer. This openness to experimentation and the adoption of new technologies, such as decentralized, censorship-resistant networks, promises to further enrich the capabilities offered by RGB.

<figure><img src="/files/y5dhB4OmDjuRgzbuzKud" alt="Several channels to acquire an RGB contract in the wallet."><figcaption><p><strong>All the various possible channels for acquiring an RGB contract in the form of consignment in a wallet.</strong></p></figcaption></figure>

**3)** Once a contract is obtained in consignment format, Bob is able to import it into his RGB wallet and validate the data contained herein. The next thing he can do is to find someone possessing the contract / asset he is interested in receiving in his wallet. In our example, Alice possesses the asset in her wallet. So, similarly to Bitcoin Transaction **they can setup an RGB Transfer.** The mechanism for discovering stakeholders who have owned states in the contract, such as Alice, remains up to the receiving party, just as the process for discovering who can pay in Bitcoin.

**4) In order to initiate a transition**, Bob must act first. It does so by **issuing an** [invoice](/annexes/glossary#invoice) that calls the specific **transfer method** encoded in the [Schema](/annexes/glossary#schema) of the contract and which he will hand over to Alice. **This invoice generation**, which precedes the effective asset transfer, guarantees that the invoice contains **all the relevant instructions needed by Alice to make the transfer**, containing in particular Bob's UTXO derived from his Bitcoin wallet encoded in [blinded form](/rgb-state-and-operations/components-of-a-contract-operation#revealed-concealed-form) or in clear. To generate the invoice to be handled to Alice, he can use the `rgb` command line tool. For example, it's possible to request an amount of 100 assets of a certain contact with the following command:

```sh
bob$ rgb invoice <ContractId> --amount 100
```

**5)** [Invoices](/annexes/glossary#invoice), which are described in more detail in this [chapter](/annexes/invoices#use-of-urls-for-invoices), are generated as simple URL strings and can be transmitted by any means in a manner similar to what we said for consignment.

<figure><img src="/files/LGqXQFsmT4jJGDj3RbRP" alt=""><figcaption><p><strong>The transfer process begins with an invoice prepared by Bob which contains all the information that Alice needs to transfer the asset, in particular Bob's seal definition, encoded as a Blinded UTXO or in clear form.</strong></p></figcaption></figure>

**6)** Alice, who has both a Bitcoin wallet and an RGB wallet with a [stash](/annexes/glossary#stash) of client-side validated data, receive the invoice from Bob, which appears to be a string like this:

* `rgb:2whK8s5O-b1LG4rR-OhXpDq1-SjyHvKx-OhTEFjQ-aba0V_o/RWhwUfTMpuP2Zfx1~j4nswCANGeJrYOqDcKelaMV4zU/BF/bc:utxob:x8H6O_~H-7RyndJZ-CAUUAcF-RJfWg7H-9hew6Zo-pacK97w-gaGhQ` , where Bob's UTXO has been blinded automatically in the generation process (for invoice encoding see the [related chapter](/annexes/invoices)).

**7)** First, Alice prepares a [PSBT](/annexes/glossary#partially-signed-bitcoin-transaction-psbt) transaction which spends the UTXO containing the [seal definition](/annexes/glossary#seal-definition) which assigns the [ownership](/annexes/glossary#ownership) of the RGB asset to her. The following represents the generic shell command of a wallet utility in order to construct the transaction which will be modified later:

```
alice$ wallet construct tx.psbt
```

**8)** Then Alice, through a shell command, is now able to generate [terminal consignment](/annexes/glossary#terminal-consignment-consignment-endpoint) `consignment.rgb` that contains, according to the instruction of Bob's `<invoice>` :

* The final RGB [state transition](/annexes/glossary#state-transition) client-side data.
* The history of state transitions since contract [genesis](/annexes/glossary#genesis) and contained in validated form in Alice's stash.
* The unsigned version of the [witness transaction](/annexes/glossary#witness-transaction), elaborated from the `tx.psbt` file, which:
  * Spend Alice's single-use seal related to the asset being transferred.
  * Contains in some first Opret / Tapret output the [DBC](/annexes/glossary#deterministic-bitcoin-commitment-dbc) commitment related to the state transition to Bob, in addition to necessary "blank" state transitions if some additional assets where defined on the same single-use seal being spent by Alice.

```sh
alice$ rgb transfer tx.psbt <invoice> consignment.rgb
```

**9)** This **terminal consignment**, obviously larger than a contract consignment because of the inclusion of the entire history of the asset, **is then forwarded to Bob**, even though the related witness transition has not yet been broadcasted into the Bitcoin P2P Network.

<figure><img src="/files/DJw6wxiVk2IJmt8TKW6Y" alt=""><figcaption><p><strong>Alice prepares a witness transaction including the information provided both by Bob's invoice and those coming from her RGB and Bitcoin wallet. In addition, through a transfer consignment allows Bob to verify all the asset history as well as the last state transition addressed to him.</strong></p></figcaption></figure>

**10)** Bob, at this point, using the `rgb accept` command proceeds at validating the transfer consignment. If the validation is successful:

* Adds all the data to his stash.
* Produce a signature of the validation process.

```sh
bob$ rgb accept consignment.rgb
sig:DbwzvSu4BZU81jEpE9FVZ3xjcyuTKWWy2gmdnaxtACrS # <— signature over consignment

```

11\) After verifying the data contained in the transfer consignment handed over by Alice, Bob may optionally send to Alice the produced signature `sig:` to Alice, in a so-called *payslip,* which confirms her that Bob:

* Agrees on the validity of the client-side validated data included in the consignment.
* Agrees that the witness transaction shall be published.

12\) Alice, by receiving the payslip:

* May validate Bob's signature.
* Publishes the witness transaction contained in the modified `tx.psbt` file using her wallet tool.

```
alice$ rgb check <sig>
alice$ wallet sign —publish tx.psbt
```

Once published, the witness transaction represents the conclusion of the transfer between Alice and Bob.

<figure><img src="/files/Tlo3YIdZOJx8uaVv4hvm" alt=""><figcaption><p><strong>Optionally Bob can sign a payslip which authorizes Alice to broadcast the witness transaction which marks the conclusion of the transfer between Alice and Bob</strong></p></figcaption></figure>

The following diagram represents a summary of all the operations just described:

<figure><img src="/files/BTOPDcNCDhLvs7NtKhml" alt=""><figcaption><p><strong>Transfer workflow diagram. The signature over consignment id can be optional.</strong></p></figcaption></figure>

Finally, the following diagram shows an example of transfer interaction between the various elements of the RGB technology stack composed of RGB wallets, RGB nodes, and Electrum Server.

<figure><img src="/files/LYI7I4um3Dpql73tiQzh" alt=""><figcaption><p><strong>The transfer process behind the scenes. It requires several round of interaction between the various components of the RGB stack.</strong></p></figcaption></figure>

## Features of RGB Transfers

**The approach adopted by RGB** in transferring consignments between parties, as illustrated in the Alice and Bob example, **underscores the significance of privacy and security**.

In the ideal case, no one other than Bob and Alice is in possession of the consignment and witness transaction. Nonetheless, Bob has all the elements to verify the validity of the consignment by comparing it with the various anchors on the Bitcoin Blockchain. Bob's stash status is consequently updated through this consignment decomposition and validation procedure. In practical transfer cases, **Alice may publish the witness transaction** to be included in the blockchain **only when some events have occurred**, such as, for example, the transfer of some object from Bob.

In this regard, it's useful to point out that the **RGB system offers a significant advantage over other digital exchange methods, especially when it comes to complex operations such as atomic swaps.** Atomic swaps, commonly used in various cryptocurrency networks, such as the Lightning network, can present complications. Typically, they require two separate transactions and the use of a hash code to ensure that both parties complete the swap almost simultaneously. **This process can create a situation where one party has the power to influence the timing of the exchange by revealing or withholding the hash code, which is known as the** ***reverse American call option problem.***

**RGB simplifies this issue considerably.** Instead of requiring two separate transactions, **RGB allows the direct exchange of one asset against another (e.g., Bitcoin against an RGB asset or an RGB asset against another RGB asset) within a single transaction**. This eliminates the need for a hash code, as both assets can be exchanged directly. If an exchange involves Bitcoin and RGB assets, both can be included in the same witness transaction output, making the process more direct and secure.

In addition, RGB introduces a **mechanism that allows both parties to have complete control over the execution of the transaction**. If the transaction is not published, both parties have the option to do so, ensuring that neither can take advantage at the expense of the other. If both parties fail to publish, the original inputs can be spent again, rendering the transaction invalid. **This approach offers a higher level of security and flexibility than traditional methods while simplifying the exchange process.**

***


# Invoices

This section explores **how invoices are structured and operate within a particular** [contract](/annexes/glossary#contract). The initial focus is on RGB identifiers, which are integral to the operation of the system and may be encountered by users in various forms. These identifiers are unique to each component of the system, including contracts and assets, ensuring a standardized method of identification throughout the system.

Each element within the system, be it a contract, schema or asset, is assigned a **unique identifier**. These identifiers are prefixed with a descriptor (in the form of a URL or URN) indicating their type, such as <mark style="color:red;">`rgb:`</mark>, which clarifies their nature.

## Enhancing Human Readability through Chunking

The concept of chunking has been introduced as a means to **enhance the readability and verifiability** of these identifiers. This technique, commonly used in phone and credit card numbers, breaks down long strings into smaller, more manageable segments. This feature not only aids in human parsing but also in verification processes, where checking the integrity of an identifier involves examining specific segments, such as the checksum at the end. Chunking, thereby, offers a balance between security and usability, with each chunk providing a certain level of security assurance. For example, having 256-bit strings divided into six blocks means that each chunk adds about 256/6 (\~42) bits of security.

An identifier for an RGB contract could be represented, by the following <mark style="color:orange;">`ContractId`</mark> encoded string:

<mark style="color:orange;">`2whK8s5O-b1LG4rR-OhXpDq1-SjyHvKx-OhTEFjQ-aba0V_o`</mark>

which, as we said, is a string divided into different chunks to make it easier to read.

## Use of URLs for Invoices

A significant advantage of this identifier system is its compatibility with URLs, allowing for direct interaction with wallets through simple clicks. This contrasts sharply with the cumbersome process required by other systems, where multiple steps are needed to copy and paste identifiers into wallets.

An example of an Invoice URL for fungible tokens might be:

<mark style="color:red;">`rgb`</mark>`:`<mark style="color:orange;">`2whK8s5O-b1LG4rR-OhXpDq1-SjyHvKx-OhTEFjQ-aba0V_o`</mark>`/`<mark style="color:blue;">`RWhwUfTMpuP2Zfx1~j4nswCANGeJrYOqDcKelaMV4zU`</mark>`/`<mark style="color:purple;">`cR`</mark>`/`<mark style="color:green;">`bc:utxob:x8H6O_~H-7RyndJZ-CAUUAcF-RJfWg7H-9hew6Zo-pacK97w-gaGhQ`</mark>

Where

* <mark style="color:red;">**`rgb:`**</mark> defines the application identifier of the URL.
* The <mark style="color:orange;">`ContractId`</mark> is the same as in the previous example.
* <mark style="color:blue;">`RWhwUfTMpuP2Zfx1~j4nswCANGeJrYOqDcKelaMV4zU`</mark> defines the schema which the contract should implement.
* The string <mark style="color:purple;">`cR`</mark> represents the amount of the requested tokens encoded in a Base32 alphabet with no digits.
* The string <mark style="color:green;">`bc:utxob:x8H6O_~H...`</mark> is the [concealed form](/rgb-state-and-operations/components-of-a-contract-operation#seal-definition) of the [seal definition](/annexes/glossary#seal-definition) that prevents Alice from knowing the UTXO actually held by Bob. The part following the `bc:utxob:` identifier is encoded in Baid64.

The URL format's simplicity and efficiency in opening wallets and facilitating transactions underscore its superiority over alternatives. Alternatives to the direct use of contract IDs, for example by using asset tickers, were considered but ultimately rejected due to security concerns and the potential for confusion. The chosen format prioritizes clarity and security, ensuring that users can easily understand and verify the details of their transactions.

The power of URLs is also expressed in the ease with which parameters such as an **invoice signature** can be introduced:

<mark style="color:red;">`rgb`</mark>`:`<mark style="color:orange;">`2whK8s5O-b1LG4rR-OhXpDq1-SjyHvKx-OhTEFjQ-aba0V_o`</mark>`/`<mark style="color:blue;">`RWhwUfTMpuP2Zfx1~j4nswCANGeJrYOqDcKelaMV4zU`</mark>`/`<mark style="color:purple;">`cR`</mark>`/`<mark style="color:green;">`bc:utxob:x8H6O_~H-7RyndJZ-CAUUAcF-RJfWg7H-9hew6Zo-pacK97w-gaGhQ`</mark><mark style="color:yellow;">`?sig=6kzbKKffP6xftkxn9UP8gWqiC41W16wYKE5CYaVhmEve`</mark>

With this invoice URL format each software is to be able to interpret the part of the invoice which it is able to execute while the other parts (e.g. the <mark style="color:yellow;">`?sig`</mark> part relate signature verification) can be safely discarded.

As for an extra example, in the box below an example of NFT transfer invoice is shown:

<mark style="color:red;">`rgb:`</mark><mark style="color:orange;">`jgOr8JoA-BSmFO9S-Z0_hGE~-pV6VQf8-d0phP06-obTe8Go`</mark>`/`<mark style="color:blue;">`~6rjymf3GTE840lb5JoXm2aFwE8eWCk3mCjOf_mUztE`</mark>`/`<mark style="color:purple;">`1@0`</mark>`/`<mark style="color:green;">`bc:utxob:x8H6O_~H-7RyndJZ-CAUUAcF-RJfWg7H-9hew6Zo-pacK97w-gaGhQ`</mark>

Where, in addition to the already described parts, the <mark style="color:purple;">`1@0`</mark> part shows that a receiver can explicitly ask to for the fraction `1` of an UDA token with index `0`.

***


# Commitments

RGB commits to client-side validated data using dedicated serialization mechanism, implemented via `CommitEncode` trait. Depending on the specific data, the mechanism can be partially or completely different from strict serialization, used for data storage. For instance, all data which may be confidential must be concealed, such that parties having no access to the original non-confidential values are still able to generate the same deterministic commitment value and verify single-use seals.

Any final consensus commitment is a SHA256 tagged hash. The tagging is performed according to BIP-340, where a commitment-specific fixed ASCII string value is first hashed with a single SHA256 hash, and the resulting 32 bytes are fed into a new SHA256 hasher twice before any actual data.

## Generating commitment id

The commitment mechanism uses traits from \[`commit_verify`] module in `rgb-consensus`, specifically its `id.rs` and `merkle.rs` submodules.

### `CommitEncode` trait

It is the main trait which must be implemented for each type requiring a dedicated commitment id.

The trait requires to define:

* `CommitmentId` specifies a commitment id type, i.e. a type wrapping 32-byte tagged SHA256 hash, implementing `CommitmentId` trait (see details below). For instance `Operation` defines `OpId` as its commitment type.
* `commit_encode` specifies an encoding for the bytestream that will be the input of the tagged hasher. Typical strategies are:
  * strict: the data is strict-serialized
  * conceal: the data is concealed and then strict-serialized
  * merkle: the data is organized in a merkle tree structure to obtain the merkle root

NB: It should never be necessary to call methods of `CommitEncode` trait directly, since `CommitId` trait automatically extends it with user-facing methods.

### `CommitmentId` trait

Each consensus commitment must have a dedicated Rust type, which wraps over inner `Bytes32` - a 32-byte resulting tagged hash value. The type is marked as a consensus commitment by implementing `CommitmentId` trait for it, which requires to provide a tag string value for the tagged hash.

The hash tags are defined using URN strings in form of `urn:<org>:<protocol>:<data>#<date>`, where `<org>` stands for the organization, `<protocol>` is the name of the protocol, `<data>` is the data type name producing the commitment, and `<date>` is a `YYYY-MM-DD` string for the latest revision of the commitment layout.

Any type implementing `CommitmentId` must also implement `From<Sha256>`, which allows for automated construction of commitments from the hasher.

### `CommitId` trait

This trait is automatically implemented for all types that implement `CommitEncode` and it can't be implemented manually. It exposes a `CommitId::commit_id()` method to produce the final commitment (i.e. the result of the hashing procedure, wrapped in the corresponding type implementing `CommitmentId`).

The trait also provides `CommitId::commitment_layout()` method, which can be used for automatically generating the documentation on the commitment workflow.

## Merklization procedure

Merklization is the procedure of computing the root of a [Merkle Tree](/annexes/glossary#merkle-tree) to be used as a commitment. It uses traits and data types from `merkle.rs` module of `commit_verify` crate and it commits to the tree parameters, such as number of elements, depth of the tree and depth of each node.

The main data type, related to the merklization, is `MerkleHash`: it is a tagged hash (using `urn:ubideco:merkle:node#2024-01-31` tag) representing node at any position of the tree: leaves, branch nodes and merkle tree root. `MerkleHash` can be produced in the following ways:

* as a result of merklization procedure, when it represents Merkle tree root;
* as a root of empty Merkle tree (i.e. collection having 0 elements), by calling `MerkleHash::void(0u8, 0u32)`,
* as a Merkle leaf, by implementing `CommitEncode` on some type and setting commitment id to be `MerkleHash`.

In all of the above cases the hash commits to the tree parameters, which makes it safe to use the same type for leaves, branches and root nodes. Specifically, it uses an intermediate structure `MerkleNode`, which is filled with information on:

* type of node branching (no branches, one branch or two branches),
* depth of the node, as 8-bit unsigned integer,
* width of the tree at its base, as a 256-bit LE unsigned integer,
* node hashes of the branches; if one or both branches are absent, they are replaced with 32 bytes of repeated 0xFF value.

A collection in form of a list (Rust `Vec`) or an ordered set of unique non-repeating items (Rust `BTreeSet`), if wrapped into a confinement (i.e. has type-defined bounds on the minimum or maximum number of items) can be automatically merklized when passed as an argument to `MerkleHash::merklize()` call. The API puts the following requirements on the collection: either

* maximum number of elements must be either 0xFF or 0xFFFF **and** each collection element must implement `CommitEncode` trait with target id set to `MerkleHash`,
* or there is a manual implementation of `MerkleLeaves` trait.

```mermaid
flowchart BT
    subgraph Merklization
        direction LR
        subgraph MerkleNode
            branching
            depth
            width
            node1
            node2
        end
        MerkleNode -- encode to\ntagged hasher --> MerkleHash
    end
    MerkleHash ---> MerkleNode
    MerkleHash === Root
    Leaf -- commit_id ----> MerkleHash
```

## Specific RGB consensus commitments

Currently, RGB has four consensus commitments: schema, operation, bundle and seal. Operation commitment for genesis has a second representation, named contract id, which uses reversed-byte encoding and a special string serialization, but is generated with the same procedure as the operation commitment.

The commitment ids can be generated with either type-specific methods (`schema_id()` for schema, `bundle_id()` for transition bundle and `id()` for any operation) or the `CommitId::commit_id()` method, which must produce the same result.

Here are more details on each commitment type:

| Commitment ID        | Produced by             | Procedure                                                                                      | Tag URN                               |
| -------------------- | ----------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- |
| `SchemaId`           | `Schema`                | strict serialization                                                                           | `urn:lnp-bp:rgb:schema#2024-02-03`    |
| `OpId`, `ContractId` | `Transition`, `Genesis` | nested commitments with concealing, merklization etc via intermediate `OpCommitment` structure | `urn:lnp-bp:rgb:operation#2024-02-03` |
| `BundleId`           | `TransitionBundle`      | conceal and partial strict serialization                                                       | `urn:lnp-bp:rgb:bundle#2024-02-03`    |
| `SecretSeal`         | `BlindSeal`             | conceal and strict serialization                                                               | `urn:lnp-bp:seals:secret#2024-02-03`  |

Additionally to these types there are three other commitment ids used internally by merklization and strict encoding procedures:

| Commitment ID     | Tag URN                                          |
| ----------------- | ------------------------------------------------ |
| `MerkleHash`      | `urn:ubideco:merkle:node#2024-01-31`             |
| `StrictHash`      | `urn:ubideco:strict-types:value-hash#2024-02-10` |
| `mpc::Commitment` | `urn:ubideco:mpc:commitment#2024-01-31`          |

`StrictHash` can be produced as a result of serialization of any strict-encodable data; for instance, it is used in compactifying collections into a single hash field in the process of computing operation ids (described below).

Finally, in `commit_verify::mpc`, multi-protocol commitment implementation, we have a type named `mpc::Commitment`, which is a commitment to a root of the MPC tree (i.e. the tree's root `MerkleHash` is tag-hashed once again to produce the final commitment value).

### Schema ID

Schema id, represented by `SchemaId` data type, is produced from `Schema` type via strict serialization of all the schema data. No conceal or merklization procedures are applied; i.e. the commitment id is the same as hashing serialized schema with the given tag.

### Operation ID and Contract ID

Operation id is represented by a `OpId` type and produced for `Genesis` and `Transition` types through a dedicated `OpCommitment` structure that is then strict-serialized and hashed.

`OpCommitment` consists of a set of commitments to blocks of the operation data, each generated with a specific procedure.

For instance, global state, inputs and assignments are merklized, such that compact proofs of inclusion can be produced and used in smart contracts. Additionally to that, assignments are concealed before the merklization, such that an entity that does not know the blinding factor can still reproduce the same operation ID. Other collections such as metadata are simply strict-serialized, producing a `StrictHash` as sub-commitment.

```mermaid
flowchart LR
  subgraph "Common data"
    Ffv --> OpCommitment
    TypeCommitment --> OpCommitment
    Metadata -- StrictHash --> OpCommitment
    Globals -- Merklize --> OpCommitment
    Inputs -- Merklize --> OpCommitment
    Assignments -- "Conceal\n + Merklize" --> OpCommitment
  end

  subgraph "Genesis"
    schemaId --> BaseCommitment
    chainNet --> BaseCommitment
  end

  subgraph "Transition"
    tcid[contractId] --> TypeCommitment
    transitionType --> TypeCommitment
  end

  BaseCommitment --> TypeCommitment

  OpCommitment -- hash --> OpId
  OpId -- "reverse bytes\n(genesis only)" --> ContractId
```

Additionally to `OpId`, genesis produces `ContractId`, which is made out of the genesis `OpId` by reversing byte order and using Base58 encoding.

### Bundle ID

Bundle id is a unique identifier of state transition bundle, directly used in constructing multi-protocol commitment tree. Bundle id commits to the mapping between assignments spent within the bundle and the id of the operation spending them. `TransitionBundle::known_transitions` may contain a subset of the transitions in the bundle and thus it doesn't contribute to the `BundleId`.

The procedure is explained in detail in a [dedicated chapter](/rgb-state-and-operations/state-transitions#transition-bundle)

```mermaid
flowchart TD
  subgraph Discarded
      id((" "))
  end

  subgraph TransitionBundle
    inputMap
    knownTransitions
  end

  inputMap -- encode \n hash --> BundleId
  knownTransitions --x Discarded
```


# RGB Library Map

## RGB Consensus

**Repository:**

* <https://github.com/rgb-protocol/rgb-consensus>

**Rust Crate:**

* <https://crates.io/crates/rgb-consensus>

## RGB Operations

**Repository:**

* <https://github.com/rgb-protocol/rgb-ops>

**Rust Crate:**

* <https://crates.io/crates/rgb-ops>
* <https://crates.io/crates/rgb-invoicing>

## RGB API and CLI

**Repository:**

* <https://github.com/rgb-protocol/rgb-api>

**Rust Crates:**

* <https://crates.io/crates/rgb-api>
* <https://crates.io/crates/rgb-psbt-utils>
* <https://crates.io/crates/rgb-cmd>

## RGB Schemas

**Repository:**

* <https://github.com/rgb-protocol/rgb-schemas/>

**Rust Crate:**

* <https://crates.io/crates/rgb-schemas>

## ALuVM

**Repository:**

* <https://github.com/rgb-protocol/rgb-aluvm>

**Rust Crate:**

* <https://crates.io/crates/rgb-aluvm>

## Strict Types

**Repositories:**

* <https://github.com/rgb-protocol/rgb-strict-types>
* <https://github.com/rgb-protocol/rgb-strict-encoding>

**Rust Crates:**

* <https://crates.io/crates/rgb-strict-types>
* <https://crates.io/crates/rgb-strict-encoding>
* <https://crates.io/crates/rgb-strict-encoding-derive>

## Ascii Armor

**Repository:**

* <https://github.com/rgb-protocol/rgb-ascii-armor>

**Rust Crate:**

* <https://crates.io/crates/rgb-ascii-armor>


# Bitcoin Single-use Seals

This section briefly describes the possible Single-use Seal structures that can be implemented using bitcoin as a publication medium and outlines the set of choices taken by the RGB protocol in particular.

There are 2 main ways in which a Single-use Seal can be **defined** in Bitcoin transactions:

* **Public keys or addresses** - the seal is defined by selecting an address or public key that has not yet been used (i.e. it has not been used by any locking script, so it is not locking any bitcoin).
* **Bitcoin transaction outputs** – the seal is defined by the selection of a specific UTxO available to some wallet.

The defined methods can be used in a combination of **closing methods** that differ according to how a **spending transaction**:

1. uses the seal definition: use of the address in the locking script or spending of the UTXO;
2. hosts the message on which the seal is closed according to a **commitment scheme** (i.e. in which part of the transaction the message is committed and stored).

The following table shows the 4 possible combinations of defining and closing a seal:

<table><thead><tr><th width="92">Seal type</th><th width="130">Seal Definition</th><th width="129">Seal Closing</th><th width="185">Additional Requirements</th><th width="117">Main application</th><th>Commitment schemes</th></tr></thead><tbody><tr><td><strong>PkO</strong></td><td>Public key value</td><td>Transaction output</td><td>P2(W)PKH</td><td>none yet</td><td>keytweak, tapret, opret</td></tr><tr><td><strong>TxO2</strong></td><td><strong>Transaction output</strong></td><td><strong>Transaction output</strong></td><td><strong>Requires Deterministic Bitcoin Commitments</strong></td><td><strong>RGB</strong></td><td><strong>keytweak, tapret, opret</strong></td></tr><tr><td><strong>PkI</strong></td><td>Public key value</td><td>Transaction input</td><td>Taproot-only - Not working with legacy wallets</td><td>Bitcoin-based identities</td><td>sigtweak, witweak</td></tr><tr><td><strong>TxOI</strong></td><td>Transaction output</td><td>Transaction input</td><td>Taproot-only - Not working with legacy wallets</td><td>none yet</td><td>sigtweak, witweak</td></tr></tbody></table>

**RGB protocol uses the TxO2** scheme in which both the Seal Definition and the Seal Closing use transaction outputs.

As shown in the table above, several **commitment schemes** can be used for each **seal type**. Each method differs in the location used by related transactions to host the commitment and, in particular, whether the message is committed to a location belonging to the input or output of the transaction:

* **Transaction Input**:
  * Sigtweak - the commitment is placed within the 32-byte random $$r$$ component that forms the ECDSA signature pair $$\<r,s>$$ of an input. It makes use of [Sign-to-contract (S2C)](https://blog.eternitywall.com/2018/04/13/sign-to-contract/#sign-to-contract).
  * Witweak - commitment is placed within the segregated witness data of the transaction.
* **Transaction Output** (scriptPubKey):
  * Keytweak - It uses the [Pay-to-contract](https://blog.eternitywall.com/2018/04/13/sign-to-contract/#pay-to-contract) construction by which the public key of the output of the output is "tweaked" (i.e. modified) to contain a deterministic reference to the message.
  * [Opret](https://github.com/rgb-protocol/RGB-Documentation/blob/master/annexes/deterministic-bitcoin-commitments-dbc/opret.md) - **used in RGB**, the committed message is placed in an unspendable output after the opcode `OP_RETURN`.
  * [Tapret](https://github.com/rgb-protocol/RGB-Documentation/blob/master/annexes/deterministic-bitcoin-commitments-dbc/tapret.md) (Taptweak) - This scheme, **used in RGB**, represents a form of tweak in which the commitment is an `OP_RETURN` leaf in the `Script path` of a [taproot output](/annexes/glossary#taproot) which then modifies the value of the PubKey.

<figure><img src="/files/942jm1mPj1raGu74SiRi" alt=""><figcaption><p><strong>The different seal closing methods in Bitcoin transaction.</strong></p></figcaption></figure>

After reading this overview, it should now be easier to dive into details of [RGB Single-use Seals](/commitment-layer/commitment-schemes#single-use-seals-in-rgb) construction.


