Ethereum (ETH) Exchange Wallet Development: Part 3 - Coin Consolidation

·

When users deposit ETH into an exchange, it's essential to periodically transfer these assets to a cold wallet. This practice enhances security and streamlines asset management.

Generating Transaction Data

The core workflow involves:

  1. Recording Deposits: All incoming ETH deposits are logged in the t_tx table with the following structure:
IDTransaction HashDeposit AddressAmountConsolidation Status
10x10xa0.110
20x20xb0.120
30x30xa0.080
40x40xc0.170

Note: Transactions #1 and #3 share the same deposit address. To optimize gas fees, these are consolidated into a single transaction.

  1. Database Storage: Consolidated transactions are stored in t_send with this schema:
CREATE TABLE `t_send` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `related_type` tinyint(4) NOT NULL COMMENT '1: Coin Consolidation, 2: Withdrawal',
  `related_id` int(11) unsigned NOT NULL COMMENT 'Reference ID',
  `tx_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Transaction Hash',
  `from_address` varchar(128) NOT NULL DEFAULT '' COMMENT 'Sender Address',
  `to_address` varchar(128) NOT NULL COMMENT 'Receiver Address',
  `balance` bigint(20) NOT NULL COMMENT 'Amount in Wei',
  `balance_real` varchar(128) NOT NULL COMMENT 'Amount in Ether',
  `gas` bigint(20) NOT NULL COMMENT 'Gas Used',
  `gas_price` bigint(20) NOT NULL COMMENT 'Gas Price',
  `nonce` int(11) NOT NULL COMMENT 'Nonce Value',
  `hex` varchar(2048) NOT NULL COMMENT 'Raw Transaction Hex',
  `create_time` bigint(20) NOT NULL COMMENT 'Creation Timestamp',
  `handle_status` tinyint(4) NOT NULL COMMENT 'Processing Status',
  `handle_msg` varchar(1024) NOT NULL DEFAULT '' COMMENT 'Status Message',
  `handle_time` bigint(20) NOT NULL COMMENT 'Processing Timestamp',
  PRIMARY KEY (`id`),
  UNIQUE KEY `related_id` (`related_id`,`related_type`) USING BTREE,
  KEY `tx_id` (`tx_id`) USING BTREE,
  KEY `t_send_from_address_idx` (`from_address`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Key Steps in Transaction Generation

  1. Retrieve Unprocessed Deposits: Fetch records where Consolidation Status = 0.
  2. Merge by Address: Sum amounts by deposit address into map[address]total_amount.
  3. Process Each Entry:

    • Retrieve the private key for the deposit address.
    • Verify the total amount exceeds the required gas fee.
    • Calculate the nonce:

      // Get maximum nonce from database or RPC
      nonce = max(dbNonce + 1, rpcNonce)
    • Create and sign the transaction:

      tx := types.NewTransaction(
        nonce,
        coldAddress,
        sendAmount,
        gasLimit,
        gasPrice,
        nil, // No data payload
      )
      signedTx := types.SignTx(tx, signer, privateKey)
  4. Update Records:

    • For the first transaction in a group: Insert full details into t_send.
    • For subsequent transactions: Record only the hash to prevent reprocessing.
    • Mark original deposits as "processed".

👉 Optimize your ETH transactions with these pro tips

Broadcasting Transactions

  1. Process Pending Transactions:

    • Deserialize stored data:

      rawTxBytes := hex.DecodeString(sendRow.Hex)
      rlp.DecodeBytes(rawTxBytes, &tx)
    • Submit via RPC:

      client.SendRawTransaction(ctx, signedTx)
  2. Update Status: Mark transactions as "broadcasted".

Transaction Confirmation

  1. Check Transaction Status:

    tx, isPending, err := client.TransactionByHash(ctx, txHash)
    if !isPending && err == nil {
        updateStatusToConfirmed()
    }
  2. Finalize Records: Update successfully mined transactions.

FAQ Section

Q: Why consolidate small ETH deposits?
A: Consolidation reduces gas fees by minimizing on-chain transactions and improves cold wallet security.

Q: How often should coin consolidation run?
A: Most exchanges run consolidation hourly or when deposit thresholds are met.

Q: What happens if consolidation fails mid-process?
A: The system uses transaction status flags to ensure idempotency - failed consolidations can safely retry.


👉 Master Ethereum wallet management with our advanced guide

This implementation is available on GitHub under go-dc-wallet (specific files omitted per guidelines). Key features include address organization, raw transaction handling, and confirmation tracking.