The Challenge of Blockchain Reorgs
When building a block explorer, the biggest architectural challenge isn't just ingesting data quickly—it's handling blockchain reorganizations (reorgs). A reorg happens when the network consensus shifts, causing previously accepted blocks to become orphaned. If your database doesn't gracefully handle this, you will end up with corrupted transaction history and incorrect balances.
Idempotent Database Design
The key to a reorg-safe explorer is an idempotent database schema. When parsing blocks, your ingestion engine must be able to overwrite or safely ignore duplicate data without throwing errors. Using PostgreSQL's ON CONFLICT DO UPDATE or ON CONFLICT DO NOTHING is essential here.
The Block Ingestion Loop
In our Go backend, we implement a robust ingestion loop:
- Fetch Block Header: Check if the block hash matches our expected
NextBlockHash. - Detect Reorg: If the block's
PreviousBlockHashdoes not match the hash of the highest block in our database, a reorg has occurred. - Rollback: We must delete all transactions, inputs, and outputs associated with the orphaned block. We trace back until we find the common ancestor.
- Re-Sync: Once the common ancestor is found, we resume syncing the new longest chain.
Satoshi-Precision Tracking
Using floating-point numbers for cryptocurrency balances is a critical mistake. In Golang, always use uint64 or the math/big package for processing raw satoshis/wei. When storing this in PostgreSQL, use the NUMERIC or BIGINT data type to prevent precision loss during aggregation queries.
Concurrent Worker Pools
To achieve high-speed syncing, especially on historical blocks, we utilize Go's goroutines to create a concurrent worker pool. The master node fetches block hashes and distributes them via channels to worker nodes. However, order matters for UTXO (Unspent Transaction Output) tracking. Therefore, historical blocks can be fetched concurrently, but UTXO state updates must be synchronized or handled in a final sequential pass.
Conclusion
Building a multi-chain explorer requires anticipating network instability. By combining an idempotent database design, precise integer math, and a reorg-aware Go ingestion loop, you can build infrastructure that handles everything the blockchain throws at it.