Skip to main content
Schema: core-chain.balances Table: ez_balances_native Type: Base Table

What

This table tracks native asset balance changes (ETH, AVAX, BNB, etc.) at the transaction level by capturing pre- and post-transaction states. It uses state tracer data to show exactly how each address’s native asset balance changed during transaction execution, including decimal adjustments and USD valuations, where available, for comprehensive balance analysis. This data set includes both successful and failed transactions, as state may change regardless.

Key Use Cases

  • Tracking native asset balance changes at transaction granularity
  • Analyzing balance impacts of smart contract interactions
  • Monitoring large balance changes and whale activity
  • Calculating precise balance evolution over time
  • Identifying addresses with significant native asset holdings
  • Debugging transaction effects on account balances

Important Relationships

  • Join with fact_transactions: Use tx_hash for transaction context
  • Join with fact_blocks: Use block_number for block metadata
  • Join with dim_labels: Use address for entity identification
  • Join with ez_native_transfers: Compare balance changes to transfer amounts
  • Join with ez_prices_hourly: USD valuations already included but can be refreshed

Commonly-used Fields

  • address: The account whose balance changed
  • pre_balance: Native asset balance before the transaction
  • post_balance: Native asset balance after the transaction
  • net_balance: The change in balance (post - pre)
  • pre_balance_usd / post_balance_usd: USD values at time of transaction
  • tx_hash: Transaction that caused the balance change
  • block_timestamp: When the balance change occurred

Sample queries

Daily Native Asset Balance Changes
SELECT
    DATE_TRUNC('day', block_timestamp) AS day,
    COUNT(*) AS balance_changes,
    COUNT(DISTINCT address) AS unique_addresses,
    SUM(ABS(net_balance)) AS total_balance_moved,
    SUM(CASE WHEN net_balance > 0 THEN net_balance ELSE 0 END) AS total_increases,
    SUM(CASE WHEN net_balance < 0 THEN ABS(net_balance) ELSE 0 END) AS total_decreases
FROM <blockchain_name>.balances.ez_balances_native
WHERE block_timestamp >= CURRENT_DATE - 30
    AND net_balance != 0
GROUP BY 1
ORDER BY 1 DESC;
Address Balance Evolution
-- Track how a specific address's balance changed over time
SELECT
    block_timestamp,
    tx_hash,
    pre_balance,
    post_balance,
    net_balance,
    pre_balance_usd,
    post_balance_usd,
    SUM(net_balance) OVER (
        PARTITION BY address
        ORDER BY block_number, tx_position
        ROWS UNBOUNDED PRECEDING
    ) AS running_balance_change
FROM <blockchain_name>.balances.ez_balances_native
WHERE address = LOWER('0x1234567890123456789012345678901234567890')
    AND block_timestamp >= CURRENT_DATE - 30
ORDER BY block_timestamp DESC;
Smart Contract Balance Impact Analysis
-- Analyze how smart contract interactions affect user balances
WITH contract_interactions AS (
    SELECT
        b.address,
        b.tx_hash,
        b.net_balance,
        b.block_timestamp,
        t.to_address AS contract_interacted
    FROM <blockchain_name>.balances.ez_balances_native b
    JOIN <blockchain_name>.core.fact_transactions t USING (tx_hash)
    WHERE b.net_balance != 0
        AND t.to_address IN (SELECT address FROM dim_contracts)
        AND b.block_timestamp >= CURRENT_DATE - 7
)
SELECT
    contract_interacted,
    dc.name AS contract_name,
    COUNT(*) AS balance_changes,
    COUNT(DISTINCT address) AS unique_users,
    SUM(CASE WHEN net_balance > 0 THEN net_balance ELSE 0 END) AS total_gains,
    SUM(CASE WHEN net_balance < 0 THEN ABS(net_balance) ELSE 0 END) AS total_losses,
    AVG(ABS(net_balance)) AS avg_balance_change
FROM contract_interactions c
LEFT JOIN <blockchain_name>.core.dim_contracts dc ON c.contract_interacted = dc.address
GROUP BY 1, 2
HAVING COUNT(*) > 10
ORDER BY total_gains + total_losses DESC
LIMIT 50;
Balance Change Distribution
-- Analyze the distribution of balance changes by magnitude
SELECT
    CASE
        WHEN ABS(net_balance) < 0.01 THEN 'Dust (<0.01)'
        WHEN ABS(net_balance) < 0.1 THEN 'Small (0.01-0.1)'
        WHEN ABS(net_balance) < 1 THEN 'Medium (0.1-1)'
        WHEN ABS(net_balance) < 10 THEN 'Large (1-10)'
        WHEN ABS(net_balance) < 100 THEN 'Very Large (10-100)'
        ELSE 'Whale (100+)'
    END AS balance_change_category,
    COUNT(*) AS change_count,
    COUNT(DISTINCT address) AS unique_addresses,
    SUM(ABS(net_balance)) AS total_volume,
    AVG(ABS(net_balance)) AS avg_magnitude
FROM <blockchain_name>.balances.ez_balances_native
WHERE block_timestamp >= CURRENT_DATE - 1
    AND net_balance != 0
GROUP BY 1
ORDER BY
    CASE balance_change_category
        WHEN 'Dust (<0.01)' THEN 1
        WHEN 'Small (0.01-0.1)' THEN 2
        WHEN 'Medium (0.1-1)' THEN 3
        WHEN 'Large (1-10)' THEN 4
        WHEN 'Very Large (10-100)' THEN 5
        WHEN 'Whale (100+)' THEN 6
    END;

Columns

Column NameData TypeDescription
BLOCK_NUMBERNUMBERSequential counter representing the position of a block in the blockchain since genesis (block 0).
Key Facts:
  • Immutable once finalized
  • Primary ordering mechanism for blockchain data
  • Increments by 1 for each new block
  • Used as a proxy for time in many analyses
Usage in Queries:
-- Recent data
WHERE block_number >= (SELECT MAX(block_number) - 1000 FROM fact_blocks)

-- Historical analysis
WHERE block_number BETWEEN 15000000 AND 16000000

-- Join across tables
JOIN <blockchain_name>.core.fact_event_logs USING (block_number)
Important: Block numbers are chain-specific. Block 15000000 on Ethereum ≠ block 15000000 on Polygon. | | BLOCK_TIMESTAMP | TIMESTAMP_NTZ | UTC timestamp when the block was produced by validators/miners. Format: TIMESTAMP_NTZ (no timezone) Precision: Second-level accuracy Reliability:
  • Set by block producer
  • Can have minor variations (±15 seconds)
  • Always increasing (newer blocks = later timestamps)
Best Practices:
-- Time-based filtering (most efficient)
WHERE block_timestamp >= DATEADD('day', -7, CURRENT_TIMESTAMP)

-- Hourly aggregations
DATE_TRUNC('hour', block_timestamp) AS hour

-- UTC date extraction
DATE(block_timestamp) AS block_date
Note: Use for time-series analysis, but be aware that block production rates vary by chain. | | TX_POSITION | NUMBER | Zero-indexed position of transaction within its block. Insights:
  • Position 0: First transaction in block
  • MEV bots often target early positions
  • Bundle transactions appear consecutively
  • Useful for analyzing transaction ordering | | TX_HASH | TEXT | Unique 66-character identifier for the transaction.
Format: 0x + 64 hexadecimal characters Usage:
  • Primary key for transaction lookups
  • Join key for traces, logs, and token transfers
  • Immutable once confirmed
Example: 0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060 | | ADDRESS | TEXT | The address whose native asset balance changed in this transaction. Example: ‘0x1234567890123456789012345678901234567890’ | | DECIMALS | NUMBER | Number of decimal places for the native asset. Typically 18 for native assets. Example: 18 | | PRE_NONCE | NUMBER | Account nonce value before the transaction execution. Example: 42 | | PRE_BALANCE_HEX | TEXT | Hexadecimal representation of the pre-transaction balance as returned by the blockchain RPC. Example: ‘0xda475abf0000000’ | | PRE_BALANCE_RAW | NUMBER | Native asset balance before transaction in smallest unit (Wei), no decimal adjustment. Example: 15750000000000000000 | | PRE_BALANCE_PRECISE | TEXT | Native asset balance before transaction, decimal adjusted, returned as a string to preserve precision. Example: ‘15.750000000000000000’ | | PRE_BALANCE | FLOAT | Native asset balance before the transaction execution, decimal adjusted to standard units. Example: 15.75 | | PRE_BALANCE_USD | FLOAT | USD value of the pre-transaction balance at the time of the transaction. Example: 39375.00 | | POST_NONCE | NUMBER | Account nonce value after the transaction execution. May be null. Example: 43 | | POST_BALANCE_HEX | TEXT | Hexadecimal representation of the post-transaction balance as returned by the blockchain RPC. Example: ‘0xaa87bee5380000’ | | POST_BALANCE_RAW | NUMBER | Native asset balance after transaction in smallest unit (Wei), no decimal adjustment. Example: 12250000000000000000 | | POST_BALANCE_PRECISE | TEXT | Native asset balance after transaction, decimal adjusted, returned as a string to preserve precision. Example: ‘12.250000000000000000’ | | POST_BALANCE | FLOAT | Native asset balance after the transaction execution, decimal adjusted to standard units. Example: 12.25 | | POST_BALANCE_USD | FLOAT | USD value of the post-transaction balance at the time of the transaction. Example: 30625.00 | | NET_BALANCE_RAW | NUMBER | The change in native asset balance in smallest unit (Wei). Example: -3500000000000000000 | | NET_BALANCE | FLOAT | The change in native asset balance (post_balance - pre_balance). Example: -3.5 | | EZ_BALANCES_NATIVE_ID | TEXT | Primary key - unique identifier for each row ensuring data integrity. Format: Usually VARCHAR containing composite key generated using MD5 hash of the relevant columns. Example: MD5(block_number, tx_hash, trace_index) Usage:
  • Deduplication in incremental loads
  • Join operations for data quality checks
  • Troubleshooting specific records
Important: Implementation varies by table - check table-specific documentation. | | INSERTED_TIMESTAMP | TIMESTAMP_NTZ | UTC timestamp when the record was first added to the Flipside database. Format: TIMESTAMP_NTZ Use Cases:
  • Data freshness monitoring
  • Incremental processing markers
  • Debugging data pipeline issues
  • SLA tracking
Query Example:
-- Check data latency
SELECT
    DATE_TRUNC('hour', block_timestamp) as block_hour,
    DATE_TRUNC('hour', inserted_timestamp) as insert_hour,
    AVG(TIMESTAMPDIFF('minute', block_timestamp, inserted_timestamp)) as avg_latency_minutes
FROM <blockchain_name>.core.fact_transactions
WHERE block_timestamp >= CURRENT_DATE - 1
GROUP BY 1, 2;
``` |
| MODIFIED_TIMESTAMP | TIMESTAMP_NTZ | UTC timestamp of the most recent update to this record.

**Format**: TIMESTAMP_NTZ

**Triggers for Updates**:
- Data corrections
- Enrichment additions
- Reprocessing for accuracy
- Schema migrations

**Monitoring Usage**:
```sql
-- Recently modified records
SELECT *
FROM <blockchain_name>.core.fact_transactions
WHERE modified_timestamp > inserted_timestamp
AND modified_timestamp >= CURRENT_DATE - 1;

-- Data quality tracking
SELECT
    DATE(modified_timestamp) as mod_date,
    COUNT(*) as records_updated,
    COUNT(DISTINCT block_number) as blocks_affected
FROM <blockchain_name>.core.fact_transactions
WHERE modified_timestamp > inserted_timestamp
GROUP BY 1
ORDER BY 1 DESC;
``` |