go-ethereum icon indicating copy to clipboard operation
go-ethereum copied to clipboard

The prestate tracer reports that the code was loaded when only the balance is read

Open pgherveou opened this issue 7 months ago • 1 comments

System information

Geth version: geth version

Geth
Version: 1.15.10-stable
Git Commit: 2bf8a78984d70e8d5a695879494b17193f1bcf57
Git Commit Date: 20250425
Architecture: amd64
Go Version: go1.24.2
Operating System: linux
GOPATH=
GOROOT=

Expected behaviour

When calling debug_traceCall for the following solidity function:

    function getExternalBalance(address account) external view returns (uint256) {
        return account.balance;
    }

I am expecting that only the balance of the address passed as argument will be read. But if the address is a contract, the trace also returns it's code

❯ DATA=$(cast calldata "getExternalBalance(address)" $OTHER_CONTRACT_ADDR)

cast rpc debug_traceCall \
  '{"to":"$CONTRACT_ADDR","data":"'"$DATA"'"}' \
  latest \
  '{"tracer":"prestateTracer", "tracerConfig": { "diffMode": false } }' --rpc-url http://localhost:8546 | jq

{
  "0x0000000000000000000000000000000000000000": {
    "balance": "0x0"
  },
  "0x20a37207f8e1b7d12ebbf678308a5056059cef76": {
    "balance": "0xffffffffffffffffffffffffffffffffffffffffffffffc8fa08cd58ce6f19c2",
    "nonce": 3
  },
  "0x7d161ee7becca09e22ebf5fc22a17eecceded6b5": {
    "balance": "0x4563918244f40000",
    "code": "<code>",
    "nonce": 1
  },
  "0xd343fdd530afc898c23f5d0db2d9849b71303425": {
    "balance": "0x8ac7230489e80000",
    "code": "<code>",
    "nonce": 1
  }
}

Actual behaviour

The code is returned in the trace, even though the contract's code should not have been read

Steps to reproduce the behaviour

  • Deploy a contract with the function above
  • Deploy another dummy contract
  • Run the cast command above to fire the rpc call

pgherveou avatar May 09 '25 16:05 pgherveou

The code is returned in the trace, even though the contract's code should not have been read

Yes the prestateTracer will return everything about that account, not just the field that was read. If you would like to exclude all contract code (e.g. for size reasons) you can by passing in disableCode: true option.

s1na avatar May 14 '25 12:05 s1na