In blockchain technology, a unique scenario can occur where two miners simultaneously package and submit a block. Subsequent miners then build upon these different blocks, creating a temporary fork. The network resolves this by adopting the longest chain as valid, discarding any blocks not included in it. This means a transaction confirmed on the abandoned chain could appear valid initially. If an exchange credits a user based on this orphaned transaction, it would result in a financial loss. To mitigate this risk, exchanges commonly wait for multiple confirmations—typically around 15 blocks—before considering a transaction final and irrevocable.
This process ensures security by allowing the network to achieve consensus and eliminate any temporary inconsistencies, protecting the exchange from accepting invalid transactions.
Understanding Blockchain Forks and Confirmations
A blockchain fork happens when two miners produce blocks at nearly the same time. The network temporarily sees two competing versions of the ledger until one chain becomes longer. The shorter chain is then discarded, along with all its transactions. This is why confirmations matter: each subsequent block added to the chain makes the transaction more secure and less likely to be reversed.
For Ethereum and similar blockchains, waiting for multiple confirmations is a standard practice to ensure transaction finality. It provides a buffer against chain reorganizations and potential double-spending attacks.
How to Monitor Transactions for Incoming Deposits
To detect incoming deposits, your system must interact with an Ethereum node, typically using JSON-RPC calls. You can query the node for block information, including details about transactions within each block.
Here’s a simplified workflow:
- Poll for New Blocks: Regularly check for new blocks added to the blockchain.
- Fetch Block Details: For each new block, retrieve its full data, including the list of transactions.
- Analyze Transactions: Iterate through each transaction in the block.
A transaction object contains critical fields for monitoring:
to: The recipient's address.value: The amount of Ether being transferred.input: Data field, often used for smart contract interactions.
Your primary focus should be on transactions where the value is greater than zero, indicating a transfer of Ether.
Processing Transaction Data
When you identify a transaction with a non-zero value, the next step is to check if the recipient address (to) matches any of the deposit addresses stored in your exchange's database. These are addresses you have generated and assigned to your users for deposits.
If a match is found, the transaction details should be recorded in a pending database table. Crucially, at this stage, the user's balance is not updated immediately. This insert operation is separate from the account credit logic, allowing for additional validation and error handling.
A common practice is to use a handle_status flag in this pending table. Newly detected transactions are inserted with a status like 0 (unprocessed). A separate, secure process later handles the actual balance updates by working through records with this unprocessed status.
👉 Explore advanced transaction monitoring strategies
Implementing the Detection Logic
The core of the detection logic involves parsing the JSON-RPC response from the Ethereum node. The provided code snippet shows an example of such a response for a mined block.
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"number": "0x96e50a",
"transactions": [
{
"to": "0xdac17f958d2ee523a2206206994597c13d831ec7",
"value": "0x0",
"input": "0xa9059cbb..."
},
{
"to": "0x787a5098678cbab92a656be84fc6ffb9345fbeee",
"value": "0x8ac7e202f94f2000",
"input": "0x"
}
]
}
}Key Extraction Steps:
- Access the
result.transactionsarray. - Loop through each transaction object in the array.
- For each transaction, check if the
valuefield is not zero. - If it is not zero, extract the
toaddress. - Query your database to see if this
toaddress exists in your list of user deposit addresses. - Upon a match, insert the transaction hash, receiving address, value (converted from Wei to Ether), and block number into your pending transactions table with a
handle_statusof0.
This approach ensures that all potential deposits are captured reliably for subsequent processing.
Best Practices for Secure Deposit Handling
- Robust Error Handling: Network calls to nodes can fail. Implement retries and fallback mechanisms.
- Idempotency: Ensure that the same transaction is not processed multiple times if your system fetches the same block more than once.
- Value Conversion: Always correctly convert values from hexadecimal format and from Wei to the base unit (Ether).
- Security: The process that updates user balances must be extremely secure, using database transactions to prevent errors and ensure data integrity.
👉 Get reliable methods for securing wallet infrastructure
Frequently Asked Questions
Why are 15 confirmations recommended for Ethereum?
While Ethereum's block time is faster than Bitcoin's, waiting for multiple confirmations provides a high safety margin against deep chain reorganizations, which are rare but possible. The exact number can vary based on an exchange's risk tolerance.
What is the purpose of the handle_status field?
The handle_status field acts as a state machine. It separates the detection of a transaction from the actual crediting of funds. This allows for easier debugging, prevents race conditions, and enables a dedicated, secure process to handle the critical balance updates.
Do I need to monitor for internal transactions?
The method described detects standard Ether transfers. However, tokens (like ERC-20) are transferred via smart contract calls. Detecting these requires parsing the input data of transactions sent to token contracts. This is a more advanced topic.
What happens if the node provides a transaction from an orphaned block?
This is why confirmations are vital. By only processing transactions from blocks that are 15+ confirmations deep, you drastically reduce the chance of handling a transaction from an orphaned block. Your system should track block confirmations before moving a transaction from pending to confirmed.
How often should I poll the Ethereum node for new blocks?
Polling frequency is a trade-off between speed and load. Polling every few seconds is common. For a production system, using a WebSocket connection to subscribe to new block headers is more efficient than frequent polling.
Is this method sufficient for detecting all deposits?
This method is perfect for native ETH deposits. For token deposits, you must monitor transactions to token contracts and decode the log events emitted by those contracts to identify transfers to your deposit addresses.