Go-ethereum: How to list contract/internal transactions via JSON-RPC API

Created on 12 Oct 2016  路  12Comments  路  Source: ethereum/go-ethereum

How do you list contract/internal transactions via JSON-RPC API? Preferably all of them in an entire block or not as efficient for a specific address?

For example: https://etherscan.io/address/0x00e41ddeb656788dc150956b6ffe175b54b61d8a#internaltx

Most helpful comment

So, there are two ways to do it.

Tracing

  1. Implement your own tracer. Example:
nc -U /datadrive/geth-devel/geth.ipc

{"id": 1, "method": "debug_subscribe", "params": ["traceChain", "0x56FEE3", "0x56FEF4", {"tracer": "{\r\narguments: [],\r\nstep: function(log, db) {\r\nif (log.op.toNumber() == 10) {\r\n    this.arguments.push({x: log.stack.peek(1).toString(16), y:  log.stack.peek(2).toString(16)})\r\n}\r\n},\r\nresult: function(){ return this.arguments;}, \r\nfault: function(){}\r\n}\r\n", "reexec":1000}]}

That example stores the argument to EXP every time the opcode is used. Some more examples of already existing tracers are here: https://github.com/ethereum/go-ethereum/tree/master/eth/tracers/internal/tracers.

This type of usage is good if you want to be able to analyze transactions programatically in-depth. If you are a programmer, and knows the VM.

Externally

If you are interested in e.g. deposits, and maintain balances, the tracing API might not be for you. There are potential pitfalls, for example - Tx A, invokes CALL b, invokes CALL c which does transfer foobar to Y. Then c suceeds ,b reverts and A succeeds. Are you confident your custom js snippet would have accounted that correctly?

If not, I would recommend using events for token-transfers, and using GetModifiedAccountsByNumber or GetModifiedAccountsByHash for ether-transfers. The latter two can tell you if one of your accounts was indeed in any way modified (such as balance added) during the block period you sent in.

All 12 comments

Use the management api, specifically debug_traceTransaction

Is there any sample code anywhere for this? It's basically decoding assembly language.

Bump. As times goes on and people use contracts more it is vital we are able to see and process these internal transactions; even telling people not to send from contracts we have to manually adjust balances and send refunds from these on a daily basis since they don't pay attention or don't know any better.

Has there been any movement on this, either through an issue or fork?

I am currently working on a project that might require this, don't mind taking a crack at extending the library.

So, there are two ways to do it.

Tracing

  1. Implement your own tracer. Example:
nc -U /datadrive/geth-devel/geth.ipc

{"id": 1, "method": "debug_subscribe", "params": ["traceChain", "0x56FEE3", "0x56FEF4", {"tracer": "{\r\narguments: [],\r\nstep: function(log, db) {\r\nif (log.op.toNumber() == 10) {\r\n    this.arguments.push({x: log.stack.peek(1).toString(16), y:  log.stack.peek(2).toString(16)})\r\n}\r\n},\r\nresult: function(){ return this.arguments;}, \r\nfault: function(){}\r\n}\r\n", "reexec":1000}]}

That example stores the argument to EXP every time the opcode is used. Some more examples of already existing tracers are here: https://github.com/ethereum/go-ethereum/tree/master/eth/tracers/internal/tracers.

This type of usage is good if you want to be able to analyze transactions programatically in-depth. If you are a programmer, and knows the VM.

Externally

If you are interested in e.g. deposits, and maintain balances, the tracing API might not be for you. There are potential pitfalls, for example - Tx A, invokes CALL b, invokes CALL c which does transfer foobar to Y. Then c suceeds ,b reverts and A succeeds. Are you confident your custom js snippet would have accounted that correctly?

If not, I would recommend using events for token-transfers, and using GetModifiedAccountsByNumber or GetModifiedAccountsByHash for ether-transfers. The latter two can tell you if one of your accounts was indeed in any way modified (such as balance added) during the block period you sent in.

I am running a local private node but got the following error

screen shot 2018-06-14 at 2 08 46 pm

what might be the error ?

Usually that means you don't have state enabled and/or that block was fast synced.

That query though... it would return all modified accounts between genesis and 51K blocks -- meaning 1) that it needs to be a full sync and 2) it will be a _humongous_ list.

@holiman In the case that I want to detect which transaction leads to change in values of wei of certain account, GetModifiedAccountsByNumber or GetModifiedAccountsByHash cannot tell me that. May I know if there are any similar methods in GETH like this ? link

@Crypto2 I tried to restart my geth node but still got the error. would you mind pointing out what might be the issue ?

For your information, the geth node is for a private net and there's only one node (itself) in this private net. The command to start geth is

geth --datadir "~/eth-private" \
  --identity "Private" \
  --networkid 15 \
  --nodiscover \
  --maxpeers 0 \
  --rpc \
  --rpcaddr "0.0.0.0" \
  --rpccorsdomain "*" \ //just for testing
  --gcmode=archive \
  --syncmode full \
  --mine

Hmm, in theory you should have state for it then (although I'm no expert)

OK, so MyEtherWallet knows what tokens I have. I plugged in my Trezor and there the tokens were. I did a trace with fiddler, and I can see the JSON RPC call to get the token's balance. I can make that call and replicate the value. But, how did MyEtherWallet know that the token was there without there being a call to get the transactions at an address?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aakilfernandes picture aakilfernandes  路  3Comments

ysqi picture ysqi  路  3Comments

VenusHu picture VenusHu  路  3Comments

wighawag picture wighawag  路  3Comments

phpsamsb picture phpsamsb  路  3Comments