- Understanding RGB contract transfer
- Advantages of RGB transfers
- Transfer summary diagram
- Invoices RGB
In this chapter, we're going to analyze the process of a contract transfer in the RGB ecosystem. To illustrate this, we'll take a look at Alice and Bob, our usual protagonists, who wish to exchange an RGB asset. We'll also show some command excerpts from the
rgb command-line tool, to see how it works in practice.Understanding RGB contract transfer
Let's take an example of a transfer between Alice and Bob. In this example, we assume that Bob is just starting to use RGB, while Alice already holds RGB assets in her wallet. We'll see how Bob sets up his environment, imports the relevant contract, then requests a transfer from Alice, and finally how Alice carries out the actual transaction on the Bitcoin blockchain.
1) Installing the RGB wallet
First of all, Bob needs to install an RGB wallet, i.e. software compatible with the protocol. This does not contain any contracts at the outset. Bob will also need:
- A Bitcoin wallet to manage your UTXOs;
- A connection to a Bitcoin node (or to an Electrum server), so that you can identify your UTXOs and propagate your transactions on the network.
As a reminder, Owned States in RGB refer to Bitcoin UTXOs. We must therefore always be able to manage and spend UTXOs in a Bitcoin transaction that incorporates cryptographic commitments (
Tapret or Opret) pointing to RGB data.2) Contract information acquisition
Bob then needs to retrieve the contract data he's interested in. This data can circulate via any channel: website, e-mail, messaging application... In practice, they are grouped together in a consignment, i.e. a small packet of data containing:
- The Genesis, which defines the initial state of the contract;
- The Schema, which describes the business logic (strict types, validation scripts, etc.);
- The Interface, which defines the presentation layer (field names, accessible operations);
- The Interface Implementation, which concretely links the Schema to the Interface.
The total size is often of the order of a few kilobytes, as each component generally weighs less than 200 bytes. It may also be possible to broadcast this consignment in Base58, via censorship-resistant channels (like Nostr or via the Lightning Network, for example), or as a QR code.
3) Contract import and validation
Once Bob has received the consignment, he imports it into his RGB wallet. This will then:
- Check that the Genesis and Schema are valid;
- Load Interface and Interface Implementation;
- Update your client-side data stash.
Bob can now see the asset in his wallet (even if he doesn't own it yet) and understand what fields are available, what operations are possible... He then needs to contact a person who actually owns the asset to be transferred. In our example, this is Alice.
The process of discovering who holds a certain RGB asset is similar to finding a Bitcoin payer. The details of this connection depend on the use (marketplaces, private chat channels, invoicing, sale of goods and services, salary...).
4) Issuing an invoice
To initiate the transfer of an RGB asset, Bob must first issue an invoice. This invoice is used to:
- Tell Alice the type of operation to be performed (for example, a
Transferfrom an RGB20 interface); - Provide Alice with Bob's seal definition (i.e. the UTXO where he wishes to receive the asset);
- Specify the quantity of active units required (e.g. 100 units).
Bob uses the
rgb tool on the command line. Suppose he wants 100 units of a token whose ContractId is known, wants to rely on Tapret, and specifies its UTXO (456e3..dfe1:0):bob$ rgb invoice RGB20 100 <ContractId> tapret1st:456e3..dfe1:0
We'll take a closer look at the structure of RGB invoices at the end of this chapter.
5) Invoice transmission
The generated invoice (e.g. as URL:
rgb:2WBcas9.../RGB20/100+utxob:...) contains all the information Alice needs to prepare the transfer. As with the consignment, it can be encoded compactly (Base58 or another format) and sent via a messaging application, e-mail, Nostr...6) Transaction preparation on the Alice side
Alice receives Bob's invoice. In her RGB wallet, she has a stash containing the asset to be transferred. To spend the UTXO containing the asset, she must first generate a PSBT (Partially Signed Bitcoin Transaction), i.e. an incomplete Bitcoin transaction, using the UTXO she has:
alice$ wallet construct tx.psbt
This basic transaction (unsigned for the moment) will be used to anchor the cryptographic commitment linked to the transfer to Bob. Alice's UTXO will thus be spent, and in the output, we'll place the
Tapret or Opret commitment for Bob.7) Generation of transfer consignment
Next, Alice builds the terminal consignment (sometimes called "transfer consignment") via the command:
alice$ rgb transfer tx.psbt <invoice> consignment.rgb
This new
consignment.rgb file contains:- The complete history of State Transitions required to validate the asset up to the present time (since Genesis);
- The new State Transition that transfers assets from Alice to Bob, according to the invoice Bob has issued;
- The incomplete Bitcoin transaction (witness transaction) (
tx.psbt), which spends Alice's Single-use Seal, modified to include the cryptographic commitment to Bob.
At this stage, the transaction is not yet broadcast on the Bitcoin network. The consignment is larger than a basic consignment, as it includes the entire history (proof chain) to prove the asset's legitimacy.
8) Bob checks and accepts the consignment
Alice transmits this terminal consignment to Bob. Bob will then:
- Check the validity of the State Transition (ensure that the history is consistent, that contract rules are respected, etc.);
- Add it to your local stash;
- Possibly generate a signature (
sig:...) on the consignment, to prove that it has been examined and approved (sometimes called a "payslip").
bob$ rgb accept consignment.rgb sig:DbwzvSu4BZU81jEpE9FVZ3xjcyuTKWWy2gmdnaxtACrS
9) Option: Bob sends confirmation back to Alice (payslip)
If Bob wishes, he can send this signature back to Alice. This indicates:
- That it recognizes the transition as valid;
- That he agrees to the Bitcoin transaction being broadcast.
This is not compulsory, but it can provide Alice with the assurance that there will be no subsequent disputes over the transfer.
10) Alice signs and publishes the transaction
Alice can then:
- Check Bob's signature (
rgb check <sig>); - Sign the witness transaction which is still a PSBT (
wallet sign); - Publish the witness transaction on the Bitcoin network (
-publish).
alice$ rgb check <sig> alice$ wallet sign —publish tx.psbt
Once confirmed, this transaction marks the conclusion of the transfer. Bob becomes the new owner of the asset: he now has an Owned State pointing to the UTXO he controls, proven by the presence of the commitment in the transaction.
To summarize, here is the complete transfer process:
Advantages of RGB transfers
- Confidentiality:
Only Alice and Bob have access to all State Transition data. They exchange this information outside the blockchain, via consignments. The cryptographic commitments in the Bitcoin transaction do not reveal the type of asset or the amount, which guarantees far greater confidentiality than other on-chain token systems.
- Customer-side validation:
Bob can check the consistency of the transfer by comparing the consignment with the anchors in the Bitcoin blockchain. He does not need third-party validation. Alice doesn't have to publish the full history on the blockchain, which reduces the load on the base protocol and improves confidentiality.
- Simplified atomicity:
Complex exchanges (atomic swaps between BTC and an RGB asset, for example) can be carried out within a single transaction, avoiding the need for HTLC or PTLC scripts. If the agreement is not broadcast, everyone can reuse their UTXOs in other ways.
Transfer summary diagram
Before looking at the invoices in more detail, here's a summary diagram of the overall flow of an RGB transfer:
- Bob installs an RGB wallet and obtains the initial contract consignment;
- Bob issues an invoice mentioning the UTXO where to receive the asset;
- Alice receives the invoice, builds the PSBT and generates the terminal consignment;
- Bob accepts it, checks, adds the data to his stash, and signs (payslip) if necessary;
- Alice publishes the transaction on the Bitcoin network;
- Confirmation of the transaction makes the transfer official.
The transfer illustrates all the power and flexibility of the RGB protocol: a private exchange, validated on the client side, anchored minimally and discreetly on the Bitcoin blockchain, and retaining the best of the protocol's security (no risk of double-spending). This makes RGB a promising ecosystem for value transfers that are more confidential and scalable than on-chain programmable blockchains.
Invoices RGB
In this section, we'll explain in detail how invoices work in the RGB ecosystem and how they enable operations (in particular transfers) to be carried out with a contract. First, we'll look at the identifiers used, then at how they are encoded, and finally at the structure of an invoice expressed as a URL (a format that's handy enough for use in wallets).
Identifiers and encoding
A unique identifier is defined for each of the following elements:
- An RGB contract;
- Its Schema (business logic);
- Its Interface and Interface Implementation;
- Its assets (tokens, NFT, etc.),
This uniqueness is very important, as each component of the system must be distinguishable. For example, a contract X must not be confused with another contract Y, and two different interfaces (RGB20 vs. RGB21, for example) must have distinct identifiers.
To make these identifiers both efficient (small size) and readable, we use:
- Base58 encoding, which avoids the use of confusing characters (e.g.
0and the letterO) and provides relatively short strings; - A prefix indicating the nature of the identifier, usually in the form of
rgb:or a similar URN.
For example, a
ContractId could be represented by something like:rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX
The
rgb: prefix confirms that this is an RGB identifier, and not an HTTP link or other protocol. Thanks to this prefix, wallets are able to interpret the string correctly.Identifier segmentation
RGB identifiers are often quite long, as the underlying (cryptographic) security may require fields of 256 bits or more. To facilitate human reading and verification, we chunk these strings into several blocks separated by a hyphen (
-). So, instead of having a long, uninterrupted string of characters, we divide it into shorter blocks. This practice is common for credit card or telephone numbers, and it also applies here for ease of verification. So, for example, a user or partner can be told: "Please check that the third block is 9GEgnyMj7", rather than having to compare the whole thing at once. The last block is often used as a checksum, in order to have an error or typos detection system.As an example, a
ContractId in base58 encoded and segmented could be:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX
Each of the dashes breaks the string into sections. This does not affect the semantics of the code, only its presentation.
Using URLs for invoices
An RGB invoice is presented as a URL. This means that it can be clicked or scanned (as a QR code), and a wallet can directly interpret it to carry out a transaction. This simplicity of interaction differs from some other systems where you have to copy and paste various pieces of data into different fields in the software.
An invoice for a fungible token (e.g. an RGB20 token) might look like this:
rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/RGB20/100+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb
Let's analyze this URL:
rgb:(prefix): indicates a link invoking the RGB protocol (analogous tohttp:orbitcoin:in other contexts);2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX: represents theContractIdof the token you want to manipulate;/RGB20/100: indicates that theRGB20interface is used and that 100 units of the asset are requested. The syntax is:/Interface/amount;+utxob:: specifies that information about the recipient UTXO (or, more precisely, the definition of the Single-use Seal) is added;egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb: this is the blinded UTXO (or seal definition). In other words, Bob has masked his exact UTXO, so the sender (Alice) doesn't know what the exact address is. She only knows that there is a valid seal referring to a UTXO controlled by Bob.
The fact that everything fits into a single URL makes life easier for the user: a simple click or scan in the wallet, and the operation is ready to be executed.
One could imagine systems where a simple ticker (e.g.
USDT) is used instead of the ContractId. However, this would raise major problems of trust and security: a ticker is not a unique reference (several contracts could claim to be called USDT). With RGB, we want a unique, unambiguous cryptographic identifier. Hence the adoption of the 256-bit string, encoded in base58 and segmented. The user knows that he is manipulating precisely the contract whose ID is 2WBcas9-yjz... and not any other.Additional URL parameters
You can also add additional parameters to the URL, in the same way as with HTTP, such as:
rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/RGB20/100+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb?sig=6kzbKKffP6xftkxn9UP8gWqiC41W16wYKE5CYaVhmEve
?sig=...: represents, for example, a signature associated with the invoice, which some wallets can verify;- If a wallet does not manage this signature, it simply ignores this parameter.
Let's take the case of an NFT via the RGB21 interface. For example, we could have:
rgb:7BKsac8-beMNMWA8r-3GEprtFh7-bjzEvGufY-aNLuU4nSN-MRsLOIK/RGB21/DbwzvSu-4BZU81jEp-E9FVZ3xj-cyuTKWWy-2gmdnaxt-ACrS+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb
Here we see:
rgb:: URL prefix;7BKsac8-beMNMWA8r-3GEprtFh7-bjzEvGufY-aNLuU4nSN-MRsLOIK: Contract ID (NFT);rGB21: interface for non-fungible assets (NFT);DbwzvSu-4BZU81jEp-...: an explicit reference to the unique part of the NFT, for example a hash of the data blob (media, metadata...);**+utxob:egXsFnw-...: the seal definition.
The idea is the same: transmit a unique link that the wallet can interpret, clearly identifying the unique asset to be transferred.
Other operations via URL
RGB URLs aren't just used to request a transfer. They can also encode more advanced operations, such as issuing new tokens (issuance). For example:
rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/RGB20/issue/100000+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb
Here we find:
rgb:: protocol;2WBcas9-...: Contract ID;/RGB20/issue/100000: indicates that you want to invoke the "Issue" transition to create an additional 100,000 tokens;+utxob:: the seal definition.
For example, the wallet might read: "I have been asked to carry out an
issue operation from the RGB20 interface, on such and such a contract, for 100,000 units, for the benefit of such and such a Single-use Seal."Now that we've looked at the main elements of RGB programming, I'll take you through the next chapter on how to draw up an RGB contract.
Quiz
Quiz1/5
csv4023.2
What is the purpose of terminal consignment in the RGB transfer process?