Skip to main content

Understanding blockchain state and transactions

Let's explore how transactions are stored and how the state is managed on Chromia. To illustrate this, let's refer back to the diagram from Lesson 1 that showed the flow of a create_book transaction:

  • User signs transaction create_book("ISBN1234", "1984", "George Orwell").
  • The transaction is sent to Chromia Node, where it is validated and then sent to the blockchain.
  • Inside the operation, the create book(isbn = isbn, title = title, author = author); is applied to the dapp table state using Rell.
  • If the transaction is confirmed, it is added to a block on the blockchain, and the dapp table state is updated.

This diagram demonstrates how a transaction is stored on the blockchain and how the state is updated from the operation within the transaction. Let's dive into this process's details and better understand the difference between the blockchain and the state.

We start by making a query fetching the state using the query get_all_books.

Query state for all books

When we execute a query like get_all_books, we only interact with the dapp table state. This makes sense because we want to fetch the current state of the books. Here's the flow for this query:

In this sequence:

  • The user queries Chromia Node for all books.
  • Chromia Node forwards the query to Rell.
  • Rell performs a query on the state to fetch all books.
  • The state executes the query and returns the result to Rell.
  • Rell provides the user with the result containing all books from the state.

Now, let's move on to querying the blockchain for all transactions.


Query blockchain for transactions

The next part is to show how we can query the blockchain and fetch all transactions that have led up to the current dapp table state.

We can do this by defining the necessary data structures and queries.

Define Data Structures

Add the following model to your src/main/entities.rell file. These are predefined Rell data structures for transactions on Chromia:

src/main/entities.rell
struct tx_op {
op_name: text;
op_args: list<gtv>;
}

struct tx_body {
tx_rid: byte_array;
ops: list<tx_op>;
signers: list<byte_array>;
}

struct tx {
tx_body;
signatures: list<byte_array>;
}

Add Query

With these models defined, add the following query to your src/main/queries.rell file. This query will fetch all transactions from the blockchain:

src/main/queries.rell
query get_transactions() {
val txs = transaction @* { } ( gtv.from_bytes(.tx_data) );
return list<tx>.from_gtv(txs.to_gtv());
}

This concludes our definitions for querying transactions. In the next lesson, we will look at how to use these queries in practice.