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