Skip to content
QuantascanAlpha

Contract calls and internal transfers

What happens when a transaction calls a smart contract, why value can move even when the headline amount is zero, and what "internal transfers" really are.

5 min readUpdated 2026-07-08

On this page

If you open a transaction on Quantascan and the amount reads 0 while wallets clearly gained or lost coins, you're almost certainly looking at a contract call with internal transfers. This guide explains both, in plain language, and clears up a common misconception.

A transaction has two layers

Every transaction has a top level — the part the sender signs:

  • from → to — who sent it and where it went.
  • value — how much Quanta the sender attached to it (often zero).
  • calldata — an optional instruction. Empty for a plain payment; filled in when you're telling a contract to do something.

A plain payment stops there: Alice sends 5 Quanta to Bob, value is 5, done. But when the to address is a smart contract, the calldata tells it which function to run, and a second layer opens up: the contract executes code.

What a "contract call" is

A contract call is simply a top-level transaction whose recipient is a contract, with calldata selecting a function — "swap these tokens", "claim my reward", "mint this NFT". The chain runs that function.

Running the function can do many things: update the contract's stored data, emit an event, move tokens, send Quanta, or call yet another contract. Or it can do almost nothing visible to balances at all.

Internal transfers: value the contract moves itself

When a contract, mid-execution, sends Quanta or calls another contract that does, each of those value-moving sub-steps is an internal transfer (some explorers call them "internal transactions").

The important part: an internal transfer is not a separate transaction. It has:

  • no hash of its own — it belongs to the one transaction you're looking at,
  • no separate fee — the single transaction fee already covers all of it,
  • no separate signature — the contract acts on its own, within the rules of the function that was called.

They aren't stored on the chain as first-class records either. The network can replay a transaction step by step to reveal them, and that's how an explorer reconstructs and shows them so your balances add up.

The misconception: "a contract call is always an internal transaction"

It isn't. These are two different things:

  • A contract call is the action — you invoked a function.
  • An internal transfer is a side effect — the contract moved value while running.

A call can happen with zero internal transfers. Approving a token allowance, changing a setting, or voting all run code but move no Quanta — so they produce none. Internal transfers appear only when the contract actually shifts value. And a plain wallet-to-wallet payment (no contract involved) never has any.

Why the headline value can be zero

Here's the case that trips people up. You call a contract with 0 value attached, but the contract pays out from its own balance:

You call a faucet's claim() with 0 Quanta. The faucet contract then sends you 0.1 Quanta from its balance. The transaction's top-level value is 0 — but you're 0.1 Quanta richer.

That 0.1 Quanta moved as an internal transfer. The top-level "value" field only ever reflects what the sender attached, not what the contract did afterwards. So "value: 0" and "coins moved" are perfectly consistent.

How Quantascan shows it

To avoid this confusion, a transaction's detail page has a "What actually changed" section. Instead of trusting the top-level value, it adds up every leg of the transaction — the attached value, each internal transfer, any token movements, and the fee — and shows the net result per wallet:

  • 🟢 received — this wallet ended up with more.
  • 🔴 sent — this wallet ended up with less.
  • paid … in network fees — the sender's one-time fee for the whole transaction.

Each asset stays in its own line, so native Quanta is never mixed up with a token. Read that section and you get the true story of the transaction, no matter how many internal steps happened behind the scenes.

Where to go next

FAQ about Contract calls and internal transfers

Common questions about this page
Is a contract call always an internal transaction?
No. A contract call runs the contract's code, but that code doesn't have to move any coins. Many calls — approving a token, updating a setting, casting a vote — finish without a single internal transfer. Internal transfers only appear when the contract itself sends Quanta or calls another contract that does.
What is an internal transfer?
An internal transfer is a movement of Quanta made by a smart contract while it runs, as part of one transaction — not a separate transaction. It has no hash or fee of its own. Explorers reconstruct these steps by replaying the transaction and show them so balances add up.
Why does the transaction show 0 value but coins still moved?
The top-level 'value' is only what the sender attached to the call. You can call a contract with 0 value and have the contract pay out from its own balance instead. That payout is an internal transfer, so the headline reads zero even though Quanta really changed hands.
Do internal transfers cost extra fees?
No. A transaction pays one fee, based on the total work (gas) it does — including any internal steps. The sender pays it once; internal transfers don't add separate fees.