INFRASTRUCTUREENGINEERING ESSAY · 7 MIN READ

Cross-chain funding attribution: evidence before interpretation

Notebook dates are an editorial chronology, separate from publication dates.

A funding trace should explain why each connection exists before it suggests who controls the money. My preferred model is an evidence graph whose edges carry provenance and explicit limits. A continuous line between two addresses is a claim about observations; it is not automatically a claim about identity.

Give every observation a reproducible address

Start with the smallest statement the data actually supports. A transaction receipt can identify an executed transaction, its containing block and emitted logs. Ethereum's JSON-RPC documentation defines those fields; it does not attach a human identity to them. I would store a chain namespace, chain identifier, block hash, transaction hash and log index beside the raw receipt. The decoder version belongs there too. If an ABI interpretation later changes, the original bytes should remain available so another reader can reproduce the observation without trusting the current interface.

Addresses need a namespace even when their hexadecimal strings look identical. EIP-155 uses a chain identifier in transaction signing to distinguish replay domains. My application-level inference is narrower: a bare address is an incomplete database key for a cross-chain investigation. I would represent an account as a pair of chain and address, then add any claimed cross-chain relationship as separate evidence. That makes accidental joins harder and preserves the possibility that identical-looking addresses have different relevant histories, contract code or custodial arrangements on the chains being examined.

References: [1] Ethereum JSON-RPC API[2] EIP-155: Simple replay attack protection

A bridge is a protocol-specific join

A bridge transfer is not a normal transaction that happens to continue somewhere else. Different designs lock and mint, burn and release, or arrange liquidity between networks. Ethereum's bridge overview describes this variety and the trust assumptions it introduces. Consequently, a generic rule that pairs equal amounts within a short time window cannot establish a bridge connection. It can generate candidates, but the candidate still needs a protocol-specific explanation: an authenticated message identifier, a nonce with its proper domain, or another relationship defined by the actual bridge.

Consider an invented transfer of 100 units on chain A followed by 99.8 units on chain B. A documented fee of 0.2 makes the arithmetic compatible, but compatibility is not uniqueness. Another user could have sent the same amount, the destination could have batched several transfers, or the relayer could have prefunded the payout. My join record would therefore include the bridge deployment, message identifier, source and destination event references, amount transformation, and the evidence used to validate the correspondence. Missing fields should weaken the claim visibly rather than silently becoming defaults.

References: [3] Ethereum developer documentation: Bridges

Conservation constrains a story without proving it

A useful worked check starts with an accounting boundary. Suppose a hypothetical address receives 100 tokens from A and 50 from B, then sends 90 to C while retaining 60. Ignoring fees and other movements, the arithmetic closes: 100 plus 50 equals 90 plus 60. Under a proportional allocation policy, 60 of C's received tokens would be associated with A and 30 with B. Under a first-in-first-out policy, all 90 would be associated with A. Both calculations use the same observed transactions and produce different attribution statements.

Neither allocation policy discovers labels physically attached to fungible token units. The policy is an analytical choice, so its name and version must travel with the result. I would expose observed inflows separately from allocated contributions and refuse to add values across assets without an explicit conversion model. Wrapped tokens, rebasing balances, transfer taxes and decimal mistakes can all invalidate a naive conservation equation. A residual is an invitation to inspect those assumptions. It should not automatically become evidence of hidden movement, and a zero residual should not automatically validate the proposed identities.

Hypothetical proportional allocation, assuming one fungible asset and no fees. text
inflow_A = 100
inflow_B = 50
outflow_C = 90
share_A = inflow_A / (inflow_A + inflow_B)
allocated_A_to_C = outflow_C * share_A = 60
unallocated_balance = 150 - 90 = 60

Finality and knowledge have different clocks

A trace also needs to distinguish when an event happened from when the system learned about it. A block may be observed promptly while an indexer delivers its logs much later. A decoder correction can change the interpretation days after both. I would retain an observation time, the chain's own position and the current canonicality assessment as separate fields. That allows a query to answer both what the chain currently supports and what an analyst could reasonably have known at an earlier moment. Those are different questions with different uses.

For a reorganisation, deleting the old edge outright loses the explanation for a previous result. A better approach is to mark the observation as orphaned and invalidate the derived joins that depend on it. Recompute downstream views from their surviving evidence, keeping the superseded result available for comparison where retention permits. This dependency tracking must cross the bridge boundary: a destination observation might remain real even while the original source interpretation becomes disputed. The system then has an unresolved relationship, not permission to invent a replacement source simply to keep the graph connected.

Confidence needs a population and a question

I would avoid assigning a number such as 97 percent confidence to a trace unless the number has a defined meaning and a measured calibration procedure. Confidence that two logs share a protocol message is different from confidence that two addresses share a controller. A model could perform extremely well at the first task and provide almost no evidence for the second. Combining those questions into one score produces a reassuring interface while obscuring the particular inference that needs scrutiny. A categorical evidence label can be more informative than an unsupported decimal.

The base rate matters even for apparently strong matching rules. Assume, purely for illustration, that one in 1,000 candidate pairs is a true match. A rule with 99 percent sensitivity and a 1 percent false-positive rate would identify about 0.99 true matches and 9.99 false matches per 1,000 candidates. Its positive results would be correct only about 9 percent of the time under those assumptions. Tightening candidate generation using authenticated protocol identifiers can be more valuable than polishing a score after a broad, ambiguous search.

The strongest objection is operational usefulness

A reasonable objection is that analysts cannot inspect every edge and still get anything done. A system that refuses to summarise uncertainty may be technically careful but operationally useless. I agree with the need for summaries. My objection is to summaries that erase the difference between a direct observation, a protocol-derived relationship and a heuristic association. A compact result can retain those distinctions through edge types, an evidence count, an unresolved-boundary indicator and a clear explanation of which question the trace actually answers.

Performance creates another tradeoff. Recomputing every path from raw receipts for every screen would be wasteful. Materialised graphs and cached attribution results are appropriate if their cache keys include the relevant chain position, decoder version and allocation policy. The difficult cache invalidation is semantic rather than merely temporal: a new decoder can invalidate an old conclusion even when no new block arrives. I would prefer a slightly stale result that clearly states its evidence boundary over a fresh-looking result whose assumptions changed invisibly between requests.

Make a trace falsifiable

The practical acceptance test is whether another person can challenge the conclusion without reverse-engineering the implementation. A useful trace should expose the exact observed events, the bridge join rule, the chosen accounting policy and the stopping condition. If the search ends at an exchange deposit address, say that the visible chain boundary ended there. If a required bridge message is unavailable, say which message is missing. A graph that can explain its stopping point is often more useful than a longer graph built from increasingly weak associations.

These are design criteria for the problem Wallet Tracer explores, not claims that a particular attribution engine has been validated or that any real address belongs to anyone. I would test the criteria using synthetic cases with known ambiguity: equal-value transfers, batched bridge payouts, orphaned source blocks, changed decoders and mixed inflows. The expected output should include deliberate unknowns. Success means preserving the difference between evidence and interpretation through storage, computation and presentation, so a reader can decide whether the supported claim is strong enough for the intended use.

Sources and further reading

  1. Ethereum JSON-RPC API

    Primary reference for receipt fields and block identifiers. The proposed evidence record and invalidation design are this essay's recommendations.

  2. EIP-155: Simple replay attack protection

    Defines chain-aware transaction signing. Namespaced analytical account keys are an application-level inference, not an identity guarantee from the EIP.

  3. Ethereum developer documentation: Bridges

    Describes bridge mechanisms and trust assumptions. The join schema and hypothetical accounting examples are original analysis.

FROM THE NOTEBOOK.

Explore wallet tracer Back to all notes