FORENSIAWeb3 forensicsOpen workspace

Did the transaction succeed

How success or failure is established from a receipt, and the five grades of certainty a record can carry.

3 min read · Transaction analysis

#Plain languageIn plain terms

A transaction being on the blockchain does not mean it worked. Transactions can fail and still be recorded, with a fee paid and nothing moved. Reading a failed transaction as a completed payment is one of the easiest mistakes in this field.

The proof of what happened is a second record called the receipt. Forensia only says a transaction succeeded when it holds the receipt and has confirmed the receipt belongs to that exact transaction in that exact block.

#How it worksHow it works

  1. Fetch the transaction, its receipt, and the block it was included in.
  2. Check that all three agree with each other.
  3. Read the status from the receipt.
  4. Grade every activity row by how well its outcome is established.

#Technical detailThe exact rules

The requests are eth_getTransactionByHash, eth_getTransactionReceipt and eth_getBlockByNumber. A receipt is accepted only when:

  • its transaction hash and block hash equal the expected ones;
  • its block number equals the expected number exactly;
  • its sender and recipient match the transaction;
  • the transaction and the receipt report the same position in the block, and the block's own transaction list holds the hash at exactly that position and nowhere else;
  • a failed receipt carries no event logs, because a failed transaction cannot leave any.

If any check fails the lookup stops with an inconsistency error. It does not guess which record is right.

The transaction's format is checked the same way. If the transaction and the receipt report different type numbers, or the transaction names a different network from the one looked up, the lookup stops without interpreting execution. A missing type is recorded as not supplied. It is not assumed to be the legacy format.

Receipt statusRead as
0x1Success
0x0Failed. The stated value was not transferred.
Anything elseUnknown. This covers very old receipts that have no status field.

The five grades

GradeWhen it applies
Receipt-confirmedA captured receipt for this exact transaction reports success.
Provider-reportedA source says it succeeded, but no bound receipt was captured.
FailedThe receipt, or the source, reports failure.
UnknownCompletion was not established.
ConflictingTwo sources disagree about the same transaction.

In an address lookup, only the newest few transactions are checked against a receipt: 4 normally, 2 on the public deployment. Fewer are checked when the lookup's request budget is nearly spent. Only top-level transactions are eligible. The rest stay provider-reported or unknown. The finding finding:address-receipt-coverage states how many were checked.

Network fees

A fee is charged whether or not execution succeeds, so it is shown apart from transfers. On the Overview view, open "Inspect transaction steps" and then "Network fees and transaction context". For Ethereum mainnet the fee is the receipt's gas used multiplied by its effective gas price, plus blob gas used multiplied by the blob gas price for a blob transaction. It is not calculated when a field is missing, malformed or contradictory, when the transaction type is outside 0 to 4, when the block has no match in the pinned fork schedule, or on other networks. A missing field is never treated as zero.

#LimitsWhat it does not tell you

  • A successful transaction says the code ran without reverting. It does not say what the code did.
  • Calls made inside a transaction can fail while the transaction as a whole succeeds. The receipt cannot confirm those.
  • Success does not establish intent, ownership or that an asset is genuine.
  • For a failed transaction, the amount shown is what was attempted, not what moved.