UTXO wallet DB Management
Amit Nadiger
Polyglot(Rust??, C++ 11,14,17,20, C, Kotlin, Java) Android TV, Cas, Blockchain, Polkadot, UTXO, Substrate, Wasm, Proxy-wasm,AndroidTV, Dvb, STB, Linux, Engineering management.
In the realm of blockchain technology, UTXO (Unspent Transaction Output)-based wallets play a crucial role in managing and facilitating transactions on networks such as Bitcoin. Efficient database management lies at the core of these wallets, ensuring smooth operation, optimal performance, and robust security. In this article, we delve into the intricacies of database management for UTXO-based wallets, exploring key concepts, challenges, and best practices.
Understanding UTXO-Based Wallets: UTXO-based wallets operate on the principle of managing a set of unspent transaction outputs. Each UTXO represents a certain amount of cryptocurrency or NFT associated with a specific output of a transaction. Wallets maintain a database that tracks these UTXOs, enabling users to perform transactions by selecting appropriate outputs and creating new ones as needed.
Key Database Management Considerations:
There are some key differences in how wallets for UTXO-based blockchains (like Bitcoin) and account-based blockchains (like Ethereum) handle building and maintaining their internal databases. Here's a breakdown:
UTXO-Based Blockchains:
Analogy: Imagine your wallet is like a physical wallet containing cash bills. Each UTXO is like a unique bill (e.g., a $10 bill). Transactions involve selecting specific bills to pay and receiving new bills as change.
Account-Based Blockchains:
Analogy: Imagine your wallet is like a bank account. You see your total balance, and transactions directly modify that balance.
Now I will explain the db management of Tuxedo blockchain .
FYI Tuxedo is UTXO based blockchain built on top of substrate framework.
Link for Tuxedo: Tuxedo: Write UTXO-based Substrate Runtimes
DB management in Tuxedo CLI-Rust wallet: Tuxedo/wallet/src/sync.rs
Design for syncing a local database with a blockchain network.?The code manages UTXO (Unspent Transaction Outputs) and maintains consistency with the blockchain.?It includes database initialization, block synchronization, transaction handling, and UTXO management functions.
There are 8 tables in the database.
You can have many tables 2 for each UTXO.1 for spent and another for unspent.
UTXO-based wallet DB building is mainly 4 steps :
Detailed steps:
Step 1: Read Node's Genesis Block Step 1.1: Retrieve Node's Genesis Block Hash
Step 1.2: Retrieve Node's Genesis Block
Step 2: Open the Database
Step 2.3: Verify Genesis Block Matching (If Database Populated)
Step 2.4: Initialize Database with Genesis Block (If Database Not Populated)
The next big step is : Synchronizing Local Database with Node in UTXO-Based Blockchain:
Below is a step-by-step explanation of the process of synchronizing a local database with the database of a running node in a UTXO-based blockchain.
Synchronize() Function Overview The synchronize function is responsible for ensuring that the local database of a wallet stays in sync with the running node's blockchain. It follows a two-step process: checking for reorganizations of blocks(re-orgs) and then synchronizing forward with the node.
FYI "re-org," occurs when there is a change in the blockchain's structure due to a divergence in the consensus of the network. This can happen when two different blocks are proposed at the same block height, leading to a temporary fork in the blockchain.
Step 1: Check for Reorganizations :
Step2: Synchronize Forward with Node
Step 3. How apply_block Function works: The apply_block function is responsible for applying a block to the local database.
Note: Transactions are also called extrinsic.
Step 4: How apply_transaction() works : The apply_transaction function is responsible for applying a single transaction to the local database.
领英推荐
Specific UTXO Implementations based on piece :
Step 1: Coin UTXO Implementation - apply_transaction in Money module. Responsibility: Store new Coin UTXOs in the global unspent outputs table. Details:
Step 2: Kitty UTXO Implementation - apply_transaction in Kitty module. Responsibility: Store new Kitty UTXOs in the local database. Details :
Similarly, we should do it for other UTXOs also such as TradableKitty, Timestamp,etc.
Spending UTXO Implementation
This means using a previously unspent output in a transaction. When an output is spent, it means that it is used as an input in a new transaction, and the funds/entity associated with that output are transferred to a new recipient or set of recipients.
Unspent Transaction Outputs (UTXOs):
Spending UTXO:
Step1: spend_output() Mark an existing output as spent by moving it from the unspent table to the spent table.
Details of implementation:
This step is necessary for the following purposes:
unapply_highest_block
The process of unapply_highest_block is part of handling a reorganization (re-org) scenario in the blockchain. In case there has been a re-org, meaning a change in the blockchain's history, this function is responsible for rolling back the local database to the previous state.
unapply_highest_block Function :
Step 1: Retrieve Information
Step 2: Unapply Transactions
Step 3: Result Return Unapplied Block: Return the unapplied block, which represents the state before the re-org.
unapply_transaction Function Overview The unapply_transaction function is responsible for undoing the effects of a transaction in the local database. This involves removing the outputs added by the transaction and marking the inputs as unspent.
1. Transaction Hash Calculation: Calculate the hash of the transaction. 2. Undo Outputs:
3. Undo Inputs:
Specific UTXO Undo Implementations We need to implement the specific UTXO undo implementation.
Unspending UTXO Implementation - unspend_output() Responsibility: Mark an existing output as unspent by moving it from the spent table back to the unspent table.
Overall this is for the recovery or rollback process of db.
Let's see some important terms :
Re-Org
What is "re-org," occurs when there is a change in the blockchain's structure due to a divergence in the consensus of the network.
This can happen when two different blocks are proposed at the same block height, leading to a temporary fork in the blockchain.
Here's how reorganizations typically occur:
Forking Point:
At a particular block height, multiple nodes in the network may simultaneously propose different blocks as the next valid block.
Temporary Fork:
The network temporarily forks into two branches, each extending from the same block height.
Competing Blocks:
Miners or validators may be working on different blocks, and both blocks are considered valid by different portions of the network.
Consensus Resolution:
The network needs to reach a consensus to determine which block will be added to the blockchain, resolving the fork.
Reorganization:
The branch with less accumulated proof-of-work or stake is typically discarded, and the other branch becomes the main chain. The discarded blocks in the alternate branch are considered orphaned.
In the context of the provided Rust code and the synchronization process, the reorganization check involves comparing the block hashes between the local wallet's database and the blockchain node's database. The synchronization algorithm loops backward from the current best height, checking whether the wallet and node agree on the best block. If there is a divergence (i.e., the wallet's hash doesn't match the node's hash at a certain height), it indicates a reorganization.
During a reorganization, the synchronization process rolls back blocks in the local wallet's database until a common ancestor block is found. This ensures that the local database aligns with the blockchain maintained by the node. Once a common ancestor is identified, the synchronization process then proceeds to sync forward from that point to catch up with the node's blockchain.
Orphaned blocks
Orphaned blocks are blocks that were initially part of the blockchain but have been discarded or abandoned due to a reorganization in the blockchain.
Orphaned blocks occur when there is a temporary fork in the blockchain, and some blocks are left without a valid continuation in the main chain.
Here's how orphaned blocks typically occur:
Consensus Resolution:
The network needs to reach a consensus to determine which block will be added to the blockchain, resolving the fork.
Orphaned Blocks:
The branch with less accumulated proof-of-work or stake is typically discarded, and the blocks in that branch become orphaned. These orphaned blocks are no longer part of the main chain.
Orphaned blocks are a natural part of blockchain systems, and they represent a divergence in the consensus of the network. When a reorganization occurs, blocks that were once considered part of the blockchain are no longer part of the main chain. This situation is handled by nodes during the synchronization process, where they may need to roll back to a common ancestor block and then sync forward from that point to align with the newly established main chain.