- State transitions and their mechanics
- Transition Bundle
- State Generation and Active State
- Genesis
- State Extension
- Components of a Contract Operation
- Status update methods and rules
- Global State
- Assignments
- Inputs
- Metadata
- Valencies
- Redeems
- RGB status characteristics
In this chapter, we'll look at how operations in smart contracts and state transitions work, again within the RGB protocol. The aim will also be to understand how several participants cooperate to transfer ownership of an asset.
State transitions and their mechanics
The general principle is still that of Client-side Validation, where state data is held by the owner and validated by the recipient. However, the specificity here with RGB lies in the fact that Bob, as recipient, asks Alice to incorporate certain information into the contract data in order to have real control over the asset received, via a hidden reference to one of his UTXOs.
To illustrate the process of a State Transition (which is one of the fundamental Contract Operations in RGB), let's take a step-by-step example of an asset transfer between Alice and Bob:
Initial situation:
Alice has a stash RGB of locally validated data (client-side). This stash refers to one of her UTXOs on Bitcoin. This means that a seal definition in this data points to a UTXO belonging to Alice. The idea is to enable her to transfer certain digital rights linked to an asset (e.g. RGB tokens) to Bob.
Bob also has UTXOs:
Bob, on the other hand, has at least one UTXO of his own, with no direct link to Alice's. In the event that Bob has no UTXO, it is still possible to make the transfer to him using the witness transaction itself: the output of this transaction will then include the commitment (commitment) and implicitly associate ownership of the new contract with Bob.
Construction of the new property (New State):
Bob sends Alice information encoded in the form of an invoice (we'll go into more detail on invoice construction in later chapters), asking her to create a new state that conforms to the rules of the contract. This state will include a new seal definition pointing to one of Bob's UTXOs. In this way, Bob is given ownership of the assets defined in this new state, for example a certain amount of RGB tokens.
Preparation of the sample transaction:
Alice then creates a Bitcoin transaction spending the UTXO referenced in the previous seal (the one that legitimized her as the holder). In the output of this transaction, a commitment (via
Opret or Tapret) is inserted to anchor the new RGB state. The Opret or Tapret commitments are derived from a MPC tree (as seen in previous chapters), which can aggregate several transitions from different contracts.Transmission of Consignment to Bob:
Before broadcasting the transaction, Alice sends Bob a Consignment containing all the necessary client-side data (his stash) and the new state information in Bob's favor. At this point, Bob applies the RGB consensus rules:
- It validates all the RGB data contained in the Consignment, including the new state which grants it ownership of the asset;
- Relying on the Anchors included in the Consignment, it verifies the chronology of witness transactions (from Genesis to the most recent transition) and validates the corresponding commitments in the blockchain.
Transition completion:
If Bob is satisfied, he may give his approval (for example, by signing the consignment). Alice can then broadcast the prepared sample transaction. Once confirmed, this closes the seal previously held by Alice and formalizes ownership by Bob. Anti-double-spending security is then based on the same mechanism as in Bitcoin: the UTXO is spent, proving that Alice can no longer reuse it.
The new state now references Bob's UTXO, giving Bob the ownership previously held by Alice. The Bitcoin output where the RGB data is anchored becomes the irrevocable proof of the transfer of ownership.
An example of a minimal DAG (Directed Acyclic Graph) comprising two contract operations (a Genesis then a State Transition) can illustrate how the RGB state (client-side layer, in red) connects to the Bitcoin blockchain (Commitment layer, in orange).
It shows that a Genesis defines a seal (seal definition), then a State Transition closes this seal to create a new one in another UTXO.
In this context, here are a few reminders of terminology:
- An Assignment combines the following:
- A Seal Definition (which points to a UTXO);
- Owned States, i.e. data linked to ownership (for example, the quantity of tokens transferred).
- A Global State brings together the general properties of the contract, visible to all, and ensuring the global consistency of evolutions.
State Transitions, described in the previous chapter, are the main form of contract operation. They refer to one or more previous states (from Genesis or another State Transition) and update them to a new state.
This diagram shows how, in a State Transition Bundle, several seals can be closed in a single sample transaction, while simultaneously opening new seals. Indeed, an interesting feature of the RGB protocol is its ability to scale: several transitions can be aggregated into a Transition Bundle, each aggregation being associated with a distinct leaf of the MPC tree (a unique bundle identifier). Thanks to the Deterministic Bitcoin Commitment (DBC) mechanism, the entire message is inserted into a
Tapret or Opret output, while closing previous seals and possibly defining new ones. The Anchor serves as a direct link between the commitment stored in the blockchain and the client-side validation structure (client-side).In the following chapters, we'll look at all the components and processes involved in building and validating a State Transition. Most of these elements are part of the RGB consensus, implemented in the RGB Core Library.
Transition Bundle
On RGB, it is possible to bundle different State Transitions belonging to the same contract (i.e. sharing the same ContractId, derived from the Genesis OpId). In the simplest case, as between Alice and Bob in the example above, a Transition Bundle contains just one transition. But support for multi-payer operations (such as coinjoins, Lightning channel openings, etc.) means that several users can combine their State Transitions in a single bundle.
Once collected, these transitions are anchored (by the MPC + DBC mechanism) in a single Bitcoin transaction:
- Each State Transition is hashed and grouped into a Transition Bundle;
- The Transition Bundle is itself hashed and inserted into the MPC tree leaf corresponding to this contract (a BundleId);
- The MPC tree is finally engaged via
OpretorTapretin the witness transaction, which thus closes the consumed seals and defines the new seals.
Technically speaking, the BundleId inserted in the MPC sheet is obtained from a tagged hash applied to the strict serialization of the bundle's InputMap field:
BundleId = SHA256( SHA256(bundle_tag) || SHA256(bundle_tag) || InputMap )
In which
bundle_tag = urn:lnp-bp:rgb:bundle#2024-02-03 for example.The InputMap is a data structure which lists, for each input
i of the sample transaction, the reference to the OpId of the corresponding State Transition. For example:InputMap = N input_0 OpId(input_0) input_1 OpId(input_1) ... input_N-1 OpId(input_N-1) |____________________| |_________||______________| |_________||______________| |__________||_______________| 16-bit Little Endian 32-bit LE 32-byte hash |_________________________| |_________________________| ... |___________________________| MapElement1 MapElement2 MapElementN
Nis the total number of entries in the transaction that refer to anOpId;opId(input_j)is the operation identifier of one of the State Transitions present in the bundle.
By referencing each entry only once and in an orderly fashion, we prevent the same seal from being spent twice in two simultaneous State Transitions.
State Generation and Active State
State Transitions can therefore be used to transfer ownership of an asset from one person to another. However, they are not the only possible operations in the RGB protocol. The protocol defines three Contract Operations:
- State Transition;
- Genesis;
- State Extension.
Among these, Genesis and State Extension are sometimes called "State Generation operations", because they create new states without immediately closing any. This is a very important point: Genesis and State Extension do not involve closing a seal. Rather, they define a new seal, which must then be spent by a subsequent State Transition to be truly validated in the blockchain history.
The Active State of a contract is often defined as the set of latest states resulting from the history (the DAG) of transactions, starting with the Genesis and following all anchors in the Bitcoin blockchain. Any old states that are already obsolete (i.e. attached to spent UTXOs) are no longer considered active, but remain essential for checking the consistency of the history.
Genesis
The Genesis is the starting point of every RGB contract. It is created by the contract issuer and defines the initial parameters, in accordance with the Schema. In the case of an RGB token, the Genesis may specify, for example:
- The number of tokens originally created and their owners;
- Total possible issue ceiling;
- Any re-issue rules, and which participants are eligible.
Being the first transaction in the contract, the Genesis does not reference any previous state, nor does it close any seal. However, to appear in the history and be validated, the Genesis must be consumed (closed) by a first State Transition (often a scan/auto-spend transaction to the issuer itself, or the initial distribution to users).
State Extension
State Extensions offer an original feature for smart contracts. They make it possible to redeem certain digital rights (Valencies) provided for in the contract definition, without immediately closing the seal. Most often, this concerns:
- Distributed token issues;
- Asset swap mechanisms;
- Conditional reissues (which may include the destruction of other assets, etc.).
Technically speaking, a State Extension references a Redeem (a particular type of RGB input) that corresponds to a Valency defined previously (for example, in Genesis or another State Transition). It defines a new seal, available to the person or condition benefiting from it. For this seal to become effective, it must be spent by a subsequent State Transition.
For example: the Genesis creates a right of issue (Valency). This can be exercised by an authorized actor, who then builds a State Extension:
- It refers to the Valency (redeem);
- It creates a new assignment (new Owned State data) pointing to a UTXO;
- A future State Transition, issued by the owner of this new UTXO, will actually transfer or distribute the newly issued tokens.
Components of a Contract Operation
I'd now like to take a detailed look at each of the constituent elements of a Contract Operation in RGB. A Contract Operation is the action which modifies the state of a contract, and which is validated on the client side, in a deterministic way, by the legitimate recipient. In particular, we'll see how the Contract Operation takes into account, on the one hand, the old state of the contract, and on the other, the definition of a new state .
+---------------------------------------------------------------------------------------------------------------------+ | Contract Operation | | | | +-----+ +-----------------------+ +--------------------------------+ +---------+ +------------+ | | | Ffv | | ContractId | SchemaId | | TransitionType | ExtensionType | | Testnet | | AltLayers1 | | | +-----+ +-----------------------+ +--------------------------------+ +---------+ +------------+ | | | | +-----------------------------------------------+ +------------------------------------------------------------+ | | | 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 | +------+ | | | +----------+ +----------------+ +-------+ | | | | +----------------+ +-------------+ +-----------------+ | | | +--------------+ | | +-------------------------------------------+ | | +--------------------------------------------------------+ | | | | | | | | | | ... ... ... | | ... ... ... | | | | | | | | | +-----------------------------------------------+ +------------------------------------------------------------+ | | | | +-----------------------------------------------+ +------------------------------------------------------------+ | | | Redeems | | Valencies | | | | | | | | | | +------------------------------+ | | | | +------+ | | | +----------+ +-------------+ | | | +-------------+ +-------------+ | | | OpId +--------------> PrevOpId | | ValencyType | | ... ... | | | ValencyType | | ValencyType | ... | | +------+ | | | +----------+ +-------------+ | | | +-------------+ +-------------+ | | | | +------------------------------+ | | | | | | | | | | | +-----------------------------------------------+ +------------------------------------------------------------+ | | | +---------------------------------------------------------------------------------------------------------------------+
If we look at the diagram above, we can see that a Contract Operation includes elements referring to the New State and others referring to the updated Old State.
The elements of the New State are:
- Assignments, in which are defined:
- The Seal Definition;
- The Owned State.
- The Global State, which can be modified or enriched;
- Valencies, possibly defined in a State Transition or Genesis.
The Old State is referenced via:
- Inputs, which point to Assignments of previous state transitions (not present in Genesis);
- Redeems, which refer to previously defined Valencies (only in State Extensions).
In addition, a Contract Operation includes more general fields specific to the operation:
ffv(Fast-forward version): 2-byte integer indicating the contract version;transitionTypeorExtensionType: 16-bit integer specifying the Transition or Extension type, according to the business logic;ContractId: 32-byte number referring to the OpId of the contract Genesis. Included in Transitions and Extensions, but not in Genesis;- schemaId: present only in Genesis, this is the 32-byte hash representing the structure (Schema) of the contract;
testnet: Boolean indicating whether you are on the Testnet or Mainnet network. Genesis only;altlayers1: variable identifying the alternative layer (sidechain or other) used to anchor data in addition to Bitcoin. Only present in Genesis;metadata: field which can store temporary information, useful for validating a complex contract, but which must not be recorded in the final status history.
Finally, all these fields are condensed by a customized hashing process, to produce a unique fingerprint, the
OpId. This OpId is then integrated into the Transition Bundle, enabling it to be authenticated and validated within the protocol.Each Contract Operation is therefore identified by a 32-byte hash named
OpId. This hash is calculated by a SHA256 hash of all the elements making up the operation. In other words, each Contract Operation has its own cryptographic commitment, which includes all the data needed to verify the authenticity and consistency of the operation.An RGB contract is then identified by a
ContractId, derived from the Genesis OpId (since there is no pre-Genesis operation). In concrete terms, we take the Genesis OpId, reverse the byte order and apply a Base58 encoding. This encoding makes the ContractId easier to handle and recognize.Status update methods and rules
The Contract State represents the set of information that the RGB protocol must track for a given contract. It is composed of:
- A single Global State: this is the public, global part of the contract, visible to all;
- One or more Owned States: each Owned State is associated with a unique seal (and therefore a UTXO on Bitcoin). A distinction is made between:
- The public Owned States,
- The private Owned States.
The Global State is directly included in the Contract Operation as a single block. The Owned States are defined in each Assignment, alongside the Seal Definition.
A major feature of RGB is the way in which the Global State and Owned States are modified. There are generally two types of behavior:
- Mutable: when a state element is described as mutable, each new operation replaces the previous state with a new state. The old data is then considered obsolete;
- Accumulating: when a state element is defined as accumulating, each new operation adds new information to the previous state, without overwriting it. The result is a kind of accumulated history.
If, in the contract, a state element is not defined as mutable or cumulative, this element will remain empty for subsequent operations (in other words, there are no new versions for this field). It's the contract Schema (i.e. the coded business logic) that determines whether a state (Global or Owned) is mutable, cumulative or fixed. Once the Genesis has been defined, these properties can only be modified if the contract itself allows it, for example via a specific State Extension.
The table below illustrates how each type of Contract Operation can manipulate (or not) the Global State and the Owned State:
| Genesis | State Extension | State Transition | |
| Addition of Global State | + | - | + |
| Mutation of Global State | n/a | - | + |
| Addition of Owned State | + | - | + |
| Mutation of Owned State | n/a | No | + |
| Addition of Valencies | + | + | + |
+: action possible if the contract's Schema allows it.-: the operation must be confirmed by a subsequent State Transition (the State Extension alone does not close the Single-use Seal).In addition, the temporal scope and update rights of each type of data can be distinguished in the following table:
| Metadata | Global State | Owned State | |
| Scope | Defined for a single Contract Operation | Defined globally for the contract | Defined for each seal (Assignment) |
| Who can update it? | Non-updatable (ephemeral data) | Operation issued by actors (issuer, etc.) | Depends on the legitimate holder who owns the seal (the one who can spend it in a following transaction) |
| Temporal Scope | Only for the current operation | State is established at the end of the operation | State is defined before the operation (by the Seal Definition of the previous operation) |
Global State
The Global State is often described as "nobody owns, everybody knows". It contains general information about the contract, which is publicly visible. For example, in a token-issuing contract, it potentially contains:
- The ticker (symbolic abbreviation of the token):
ticker; - The full name of the token:
name; - Precision (number of decimal places):
precision; - Initial offer (and/or maximum token limit):
issuedSupply; - Issue date:
created; - Legal data or other public information:
data.
This Global State can be placed on public resources (websites, IPFS, Nostr, Torrent, etc.) and distributed to the community. Also, the economic incentive (the need to hold and transfer these tokens, etc.) naturally drives contract users to maintain and propagate this data themselves.
Assignments
The Assignment is the basic structure for defining:
- The seal (Seal Definition), which points to a specific UTXO;
- The Owned State, i.e. the property or data associated with this seal.
An Assignment can be seen as the analogue of a Bitcoin transaction output, but with more flexibility. Herein lies the logic of property transfer: the Assignment associates a particular type of asset or right (
AssignmentType) with a seal. Whoever possesses the private key of the UTXO linked to this seal (or whoever can spend this UTXO) is considered the owner of this Owned State.One of RGB's great strengths lies in the ability to reveal or hide (conceal) the Seal Definition and Owned State fields at will. This offers a powerful combination of confidentiality and selectivity. For example, you can prove that a transition is valid without disclosing all the data, by providing the revealed version to the person who has to validate it, while third parties only see the hidden version (a hash). In practice, the
OpId of a transition is always calculated from the concealed data.Seal Definition
The Seal Definition, in its revealed form, has four basic fields:
txptr, vout, blinding and method:- txptr: this is a reference to a UTXO on Bitcoin:
- In the case of a Genesis seal, it points directly to an existing UTXO (the one associated with the Genesis);
- In the case of a Graph seal, we can have:
- A simple
txid, if pointing to a specific UTXO, - Or a
WitnessTx, which designates a self-reference: the seal points to the transaction itself. This is particularly useful when no external UTXO is available, for example in Lightning channel opening transactions, or if the recipient has no UTXO.
- A simple
- vout: the output number of the transaction indicated by
txptr. Present only for a standard Graph seal (not forWitnessTx); - blinding: a random number of 8 bytes, to reinforce confidentiality and prevent brute force attempts on the UTXO's identity;
- method: indicates the anchoring method used (
TapretorOpret).
The concealed form of the Seal Definition is a SHA256 hash (tagged) of the concatenation of these 4 fields, with a tag specific to RGB.
Owned States
The second component of Assignment is the Owned State. Unlike the Global State, it can exist in public or private form:
- Public Owned State: everyone knows the data associated with the seal. For example, a public image;
- Private Owned State: the data is hidden, known only to the owner (and potentially the validator if necessary). For example, the number of tokens held.
RGB defines four possible state types (StateTypes) for an Owned State:
- Declarative: contains no numerical data, just a declarative right (e.g. a right to vote). The hidden and revealed forms are identical;
- Fungible: represents a fungible quantity (like tokens). In revealed form, we have
amountandblinding. In hidden form, we have a single Pedersen commitment which hides the amount and the blinding; - Structured: stores structured data (up to 64 kB). In revealed form, it's the data blob. In hidden form, it's a tagged hash of this blob:
SHA-256(SHA-256(tag_data) || SHA-256(tag_data) || blob)
With, for example:
tag_data = urn:lnp-bp:rgb:state-data#2024-02-12
- Attachments: links a file (audio, image, binary, etc.) to the Owned State, storing the file hash
file_hash, the MIME typemedia typeand a cryptographic saltsalt. The file itself is hosted elsewhere. In hidden form, it is a hash tagged with the three preceding data items:
SHA-256(SHA-256(tag_attachment) || SHA-256(tag_attachment) || file_hash || media_type || salt)
With, for example:
tag_attachment = urn:rgb:state-attach#2024-02-12
To summarize, here are the 4 possible types of state in the public and hidden form:
State Concealed form Revealed form +--------------------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------+ | | Declarative | < void > | | | +--------------------------------------------------------------------------------+ +--------------------------------------------------------------------------------------------------------- +--------------------------+ +---------------------------------------+ | +----------------------+ | | +--------+ +----------+ | Fungible | | Pedersen Commitement | | <========== | | Amount | | Blinding | | | +----------------------+ | | +--------+ +----------+ | +--------------------------+ +---------------------------------------+ +--------------------------------------------------------------------------------------------------------- +--------------------------+ +---------------------------------------+ | +----------------------+ | | +--------------------+ | Structured | | Tagged Hash | | <========== | | Data Blob | | | +----------------------+ | | +--------------------+ | +--------------------------+ +---------------------------------------+ +--------------------------------------------------------------------------------------------------------- +--------------------------+ +---------------------------------------+ | +----------------------+ | | +-----------+ +------------+ +------+ | Attachments | | Tagged Hash | | <========== | | File Hash | | Media Type | | Salt | | | +----------------------+ | | +-----------+ +------------+ +------+ | +--------------------------+ +---------------------------------------+
| Element | Declarative | Fungible | Structured | Attachments |
| Data | None | Signed or unsigned 64-bit integer | Any strict data type | Any file |
| Info Type | None | Signed or unsigned | Strict types | MIME Type |
| Privacy | Not required | Pedersen commitment | Hash with blinding | Hashed file identifier |
| Size Limits | N/A | 256 bytes | Up to 64 KB | Up to ~500 GB |
Inputs
The Inputs of a Contract Operation refer to the Assignments that are being spent in this new operation. An Input indicates:
prevOpId: the identifier (OpId) of the previous operation where the Assignment was located;assignmentType: the type of Assignment (for example,assetOwnerfor a token);Index: the index of the Assignment in the list associated with the previousOpId, determined after a lexicographic sorting of the hidden seals.
Inputs never appear in Genesis, since there are no previous Assignments. Nor do they appear in State Extensions (because State Extensions don't close seals; rather, they redefine new seals based on Valencies).
When we have Owned States of type
Fungible, the validation logic (via the AluVM script provided in the Schema) checks the consistency of the sums: the sum of incoming tokens (Inputs) must be equal to the sum of outgoing tokens (in the new Assignments).Metadata
The Metadata field can be up to 64 KiB and is used to include temporary data useful for validation, but not integrated into the permanent state of the contract. For example, intermediate calculation variables for complex scripts can be stored here. This space is not intended to be stored in the global history, which is why it is outside the scope of Owned States or Global State.
Valencies
Valencies are an original RGB protocol mechanism. They can be found in Genesis, State Transitions or State Extensions. They represent numerical rights that can be activated by a State Extension (via Redeems), then finalized by a subsequent Transition. Each Valency is identified by a
ValencyType (16 bits). Its semantics (reissue right, token swap, burn right, etc.) are defined in the Schema.In concrete terms, we could imagine a Genesis defining a "right to reissue" valency. A State Extension will consume it (Redeem) if certain conditions are met, in order to introduce a new quantity of tokens. Then, a State Transition emanating from the holder of the seal thus created can transfer these new tokens.
Redeems
Redeems are the Valency equivalent of Inputs for Assignments. They only appear in State Extensions, as this is where a previously defined Valency is activated. A Redeem consists of two fields:
PrevOpId: theOpIdof the operation where the Valency was specified;ValencyType: the type of Valency you wish to activate (eachValencyTypecan only be used once by State Extension).
Example: a Redeem can correspond to a CoinSwap execution, depending on what was coded in the Valency.
RGB status characteristics
We're now going to take a look at several fundamental state characteristics in RGB. In particular, we'll look at:
- The Strict Type System, which imposes a precise and typed organization of data;
- The importance of separating validation from ownership;
- The consensus evolution system in RGB, which includes the notions of fast-forward and push-back.
As always, bear in mind that everything to do with contract status is validated on the client side according to consensus rules set out in the protocol, and whose ultimate cryptographic reference is anchored in Bitcoin transactions.
Strict Type System
RGB uses a Strict Type System and a deterministic serialization mode (Strict Encoding). This organization is designed to guarantee perfect reproducibility and precision in the definition, handling and validation of contract data.
In many programming environments (JSON, YAML...), the data structure can be flexible, even too permissive. In RGB, on the other hand, the Structure and Types of each field are defined with explicit constraints. For example:
- Each variable has a specific type (for example, an 8-bit unsigned integer
u8, or a 16-bit signed integer, etc.); - Types can be composed (nested types). This means you can define a type based on other types (e.g. an aggregate type containing a
u8field, aboolfield, etc.); - Collections can also be specified: lists (list), sets (set) or dictionaries (map), with a deterministic order of progression;
- Each field is bounded (lower bound / upper bound). We also impose limits on the number of elements in collections (containment);
- Data is byte-aligned and serialization is strictly defined and unambiguous.
Thanks to this strict encoding protocol:
- The order of the fields is always the same, regardless of the implementation or programming language used;
- The hashes calculated on the same data set are therefore reproducible and identical (strictly deterministic commitments);
- Boundaries prevent uncontrolled growth in data size (e.g. too many fields);
- This form of encoding facilitates cryptographic verification, as each participant knows exactly how to serialize and hash the data.
In practice, the structure (Schema) and the resulting code (Interface and associated logic) are compiled. A descriptive language is used to define the contract (types, fields, rules) and generate a strict binary format. When compiled, the result is:
- A Memory Layout for each field;
- Semantic identifiers (which indicate whether changing a variable name has an impact on the logic, even if the memory structure remains the same).
The strict type system also enables precise monitoring of changes: any modification to the structure (even a change of field name) is detectable and can lead to a change in the overall footprint.
Finally, each compilation produces a fingerprint, a cryptographic identifier that attests to the exact version of the code (data, rules, validation). For example, an identifier of the form:
BEiLYE-am9WhTW1-oK8cpvw4-FEMtzMrf-mKocuGZn-qWK6YF#ginger-parking-nirvana
This makes it possible to manage consensus or implementation updates, while ensuring detailed traceability of the versions used in the network.
To prevent the state of an RGB contract from becoming too cumbersome to validate on the client side, a consensus rule imposes a maximum size of
2^16 bytes (64 KiB) for any data involved in validation calculations. This applies to each variable or structure: no more than 65536 bytes, or the equivalent in numbers (32768 16-bit integers, etc.). This also applies to collections (lists, sets, maps), which may not exceed 2^16 elements.This limit guarantees:
- Controls the maximum size of data to be manipulated during a state transition;
- Compatibility with the virtual machine (AluVM) used to run the validation scripts.
The Validation != Ownership paradigm
One of RGB's major innovations is the strict separation between two concepts:
- Validation: checking that a state transition respects the rules of the contract (business logic, history, etc.);
- The ownership (ownership, or control): the fact of owning the Bitcoin UTXO that allows the Single-use Seal to be spent (or closed), and thus the state transition to take place.
Validation takes place at the level of the RGB software stack (libraries, commitments protocol, etc.). Its role is to ensure that the internal rules of the contract (amounts, permissions, etc.) are respected. Observers or other participants can also validate the data history.
Ownership, on the other hand, relies entirely on Bitcoin's security. Owning the private key of a UTXO means controlling the ability to launch a new transition (closing the Single-use Seal). So, even if someone can see or validate the data, they can't change the state if they don't own the UTXO concerned.
This approach limits the classic vulnerabilities encountered in more complex blockchains (where all the code of a smart contract is public and modifiable by anyone, which has sometimes led to hacks). On RGB, an attacker cannot simply interact with the on-chain state, as the right to act on the state (ownership) is protected by the Bitcoin layer.
What's more, this decoupling allows RGB to integrate naturally with the Lightning Network. Lightning channels can be used to engage and move RGB assets without engaging on-chain commitments every time. We'll take a closer look at this integration of RGB on Lightning in later chapters of the course.
Consensus developments in RGB
In addition to semantic code versioning, RGB includes a system for evolving or updating a contract's consensus rules over time. There are two main forms of evolution:
- Fast-forward
- Push-back
A fast-forward occurs when a previously invalid rule becomes valid. For example, if the contract evolves to allow a new type of
AssignmentType or a new field:- This cannot be compared to a classic blockchain hardfork, as RGB works in client-side validation and does not affect the overall compatibility of the blockchain;
- In practical terms, this type of change is indicated by the
Ffv(fast-forward version) field in the contract operation; - Current holders are not harmed: their status remains valid;
- New beneficiaries (or new users), on the other hand, need to update their software (their wallet) to recognize the new rules.
A push-back means that a previously valid rule becomes invalid. It is therefore a "hardening" of the rules, but not strictly speaking a softfork:
- Existing holders may be impacted (they could find themselves with assets rendered obsolete or invalid in the new version);
- We can consider that we are in fact creating a new protocol: whoever adopts the new rule departs from the old one;
- The issuer may decide to re-issue assets in this new protocol, forcing users to maintain two separate wallets (one for the old protocol, the other for the new), if they want to manage both versions.
In this chapter on RGB contract operations, we've explored the fundamental principles underlying this protocol. As you will have noticed, the inherent complexity of the RGB protocol requires the use of many technical terms. So, in the next chapter, I'll provide you with a glossary that will summarize all the concepts covered in this first theoretical part, with definitions of all the technical terms relating to RGB. Then, in the next section, we'll take a practical look at the definition and implementation of RGB contracts.
Quiz
Quiz1/5
csv4022.4
What does a Consignment in RGB contain?