Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute internal transaction call graph #46

Open
nventuro opened this issue May 11, 2020 · 4 comments
Open

Compute internal transaction call graph #46

nventuro opened this issue May 11, 2020 · 4 comments
Labels
enhancement New feature or request

Comments

@nventuro
Copy link

Ethereum blocks are made up of transactions, which are one of the things ethlogger currently tracks. However, richer information can be extracted from these. A transaction that targets or crates a smart contract can in turn spawn new so-called 'internal' transactions by executing the CALL, STATICCALL and DELEGATECALL opcodes.

Internal transactions are similar to regular ones, and have pretty much the same attributes: from, to, data, value, gas, gasprice (this value cannot be changed), and execution status (success, revert, invalid opcode, out of gas).

This issue is intended to gather ideas and feedback around why and how internal transactions might be tracked by ethlogger.

Why

Any transaction monitoring should include internal transactions: just looking at outer calls provides an incomplete view of on-chain activity. Many contracts and usage patterns revolve exclusively around internal transactions, including smart accounts and contracts intended to be used by other contracts. A prime example is the ERC1820 Registry Contract: at a glance it never had any activity, but looking at the internal transactions makes it clear that it's actually heavily used.

The call graph of all addresses involved in a transaction also provides information that cannot be otherwise obtained. It can be used to detect contract re-entrancy, learn about internal reverted calls, or even flag suspicious transactions that involve a large number of platforms.

As an example, the recent bZx hack took place in an apparently harmless transaction. Emitted events show lots of activity, but are not easy to follow. The internal call graph however shows a large number of calls with large Ether values to a number of DeFi systems, and is a tool much better suited to analyse what happened.

How

Construction of the call graph requires knowledge of the opcodes executed by the EVM in a transaction, along with environment information (e.g. status of the EVM stack). There's two big possible approaches that I know of that can be taken here.

The hardcore route would be taking an EVM implementation (such as ethereumjs-vm), and adding instrumentation on top of it to detect internal calls. Note that there is already official support for doing this, though some encapsulation around it would be beneficial.

Alternatively, it is possible to use traces over JSON-RPC to obtain this data. Notably, the debug_traceTransaction method provides detailed execution information that should be enough to obtain the required result. A challenge here is restricting what data is saved to achieve good performance, both in terms of speed, memory, and network usage. Follow the links for more details and suggestions on this topic.

Note that both approaches require a 'special' node that is either instrumented or provides access to debugging methods: this will likely translate into an infrastructure requirement for people using ethlogger to get this information. The introspection features would likely come into play here.

@sambacha
Copy link

The problem is that not even geth conforms to its own specification, with undocumented API's available. A solution is using something like trueblocks

also just to illustrate your point, block explorers vary widely in the available information, here is that same transaction you linked but from another service provider, ethtx.info; https://ethtx.info/mainnet/0xb5c8bd9430b6cc87a0e2fe110ece6bf527fa4f170a4bc8cd032f768fc5219838

trueblocks does traces over RPC well of course it requires a contract ABI as well.

https://tenderly.dev - although this solution did miss the tBTC exploit

https://github.com/blocknative - more oriented for "in flight" transactions, has visibility at the mempool level, which is far beyond what most can even obtain

@nventuro
Copy link
Author

nventuro commented Jun 1, 2020

I had not heard about TrueBlocks (which seems to also be called QuickBlocks?) before, but at a glance it doesn't seem like it might be the best choice to build on top of. There even seems to be some overlap between it and ethlogger.

Could you expand on what you mean by undocumented APIs? As far as I know, the debug_traceTransaction method is quite stable and well-documented, and is used by projects such as 0x's sol-trace.

@ziegfried ziegfried added the enhancement New feature or request label Jun 4, 2020
@kthomas
Copy link

kthomas commented Jun 16, 2020

debug_traceTransaction indeed works for this. I have a solution I can share if needed. Would be nice to see this in splunk.

@ziegfried
Copy link
Contributor

@kthomas that'd be great, please share! I'm about to start looking into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants