2

I am using trace_call with stateDiff Tracer, to show balances changes after a transaction. Already tried to use Erigon and core-geth, the results are identical thoughout changes in usage.

For instance, this tx: https://goerli.etherscan.io/tx/0xffa922bc144466247cf1d94db849ae80d36c9d75b300636d6dc68d7ef6c6c114 generate this trace:

[
  {
    "statediff": {
      "0xd44fbeb26c88f0f18f72664e3c446e0c2836908d": {
        "balance": "=",
        "nonce": {
          "*": {
            "from": "0x209",
            "to": "0x20a"
          }
        },
        "code": "=",
        "storage": {}
      }
    }
  }
]

there is no changes in balances, but yes there was, as one can see in etherscan "state" flap. I've noted that this happens always in internal txs, and when there are no internals, the result is expected. Someone can explain why internal tx are not captured by trace? And more important, how to trace Internal Txs and show balance changes?

13
  • this state change is the increment of nonce on the Sender's account, on every transaction Ethereum increments your nonce, that's standard behavior
    – Nulik
    Feb 2 at 1:37
  • the transaction you link in Etherscan shows all the traces perfectly. you probably should put all the steps you are doing, then what is expected, and what is happening in reality so we can undersand you
    – Nulik
    Feb 2 at 1:39
  • note: balances of tokens is not the same as balances in ETH. the balance in ETH is stored in Ethereum merkle trie, the balance of the token is stored in the storage slot that belongs to the storage trie of the contract
    – Nulik
    Feb 2 at 1:41
  • The expected is the "state" from etherscan, i am getting the trace above (are the same transaction). The storage changes from internal txs are missing in the trace.
    – Rafael
    Feb 2 at 2:10
  • I am using trace_callMany, can't post the code here
    – Rafael
    Feb 2 at 2:27

1 Answer 1

2

Hi Developer advocate from Chainstack here

I can't tell if the full trace is working but

[
  {
    "statediff": {
      "0xd44fbeb26c88f0f18f72664e3c446e0c2836908d": {
        "balance": "=",
        "nonce": {
          "*": {
            "from": "0x209",
            "to": "0x20a"
          }
        },
        "code": "=",
        "storage": {}
      }
    }
  }
]

is perfectly correct.

This is a transaction swapping 0.07 WETH for ApeIn, during the tx, the sender 0xd44fbeb26c88f0f18f72664e3c446e0c2836908d doesn't really lose any Eth except for his gas fee, which won't reflect in a trace_call.

A trace_call basically "simulates" a call against a specific "state", the gas fee is undetermined until the tx is finalized in a block. Hence it is not part of this "simulation". If you trace it using trace_transaction, you will probably see the balance reduce due to gas.

Your confusion comes from Etherscan incorrectly using the word "state" here. Maybe it has a different understanding from Geth, but here it certainly mixes Eth(the native currency) and WETH(wrapped Eth, a token) together.

traceCall with stateDiff doesn't trace smart contract data changes, as Nulik pointed out, that should be a storage change. You can use debug_traceCall with disableStorage:false to trace this changes.

I had two blog posts: this is about eth_call, this is about debug_trace API. There are some examples that may help you.

Hope you find it useful, Happy coding!

1
  • This is a trace_call complete, with changes in storage. From this tx. trace_call shows changes in storage, but when the tx have internal txs it not showing anymore, like the example given in the question. debug_traceCall is equivalente to trace_call, except for the response squema (source).
    – Rafael
    Feb 2 at 10:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.