Why internal ETH transfers are not in logs
Last updated:
At a glance
| Property | Value |
|---|---|
| When logs exist | Only when contract code emits an event |
| Internal ether transfer | A call with value — no log of its own |
| Receipt contents | Logs generated during execution, not internal calls |
| How to see them | A call tracer: every call frame with from, to and value |
What you see
A wallet received ether from a contract — its balance went up — but eth_getLogs finds nothing and the transaction's receipt has no entry for the transfer. The top-level transaction's value is 0 or goes to a different address.
Why this happens
Solidity uses logs "to implement events": a log exists only when code emits an event. Sending ether is a call with a value, which changes balances but emits no log of its own, and a receipt contains the logs generated during execution, not a list of calls. So an ether transfer made inside a contract — a withdrawal, a refund, a multisig payout — is invisible to eth_getLogs and receipts unless the contract also emits an event. Geth's callTracer "tracks all the call frames executed during a transaction", and each frame carries its type, from, to and value, which is where internal transfers show up.
What to do
- Check whether the contract emits an event for the transfer; if it does, filter for that event instead of tracing.
- Otherwise trace the transaction (debug_traceTransaction with the call tracer, or trace_transaction where available) and collect frames with a non-zero value.
- For balance tracking without traces, compare eth_getBalance before and after the block — it shows that ether moved, not who sent it.
When this is not our problem
That value transfers leave no log is a property of the EVM on every chain that runs it, whoever operates the node, Triport included. Only tracing, or the contract's own events, can show them.
FAQ
- What is an internal transaction in Ethereum?
- An informal name for a call made by a contract during execution — often an ether transfer. It is not a separate transaction and has no receipt; tracing reveals it.
- Why doesn't eth_getLogs show ETH I received from a contract?
- Because sending ether emits no log. Unless the contract emits its own event, only a trace of the transaction shows the transfer.