I am trying to understand how the call stack inside the EVM works. I can't find anything in the yellow paper not else where online. Can anyone explain how the call stack works and if you can access its values in any way (EVM or solidity)?
-
1The communication between contracts "calls" is done through message calls (YP section 8). Each contract call is isolated only sharing the sender and the call data. There's no standard way of iterating the message call chain. Some implementation like remix can show it is specific to them.– Ismael ♦May 4, 2018 at 3:03
-
What do you mean by the call stack? Do you mean how the stack in general works or how function calls internally in a contract (to functions within the same contract) works? Or do you mean how function calls from one contract to another works?– Thorkil VærgeMay 25, 2018 at 16:33
1 Answer
How does the call stack work
Formal Specification
I found a formal specification of the call stack in the paper Making smart contracts smarter by Luu et al. They specify a formal definition of the operational semantics of Ethereum in Section 4.1 and they formalize also the call stack.
I add also the screenshot of the definition of the call stack.
Essentially, as already pointed out by @ismael each call has its own Stack, Memory, Program counter and Contract code and therefore each execution is isolated. Each time a call is performed, the executor checks if the call stack size does not exceed the 1024 size, and adds the new activation record.
Go-Ethereum Implementation
If you take a look to the go-ethereum implementation file core/vm/instruction.go
, the function opCallCode
, you can see that the implementation uses the stack of the language rather an explicit stack:
https://github.com/ethereum/go-ethereum/blob/master/core/vm/instructions.go,
indeed when a call is performed a new function with its own machine state is created.
Can one access the call stack values in any way (EVM or solidity)?
In the yellow paper I cannot find a particular instruction to access neither previous call stack's activation records nor the actual call stack height. The only information available are those specified by @ismael "sender and the call data" and also after the completion of the callee the caller has on top of its stack a 0 if the callee execution failed (because of an exception) or 1 otherwise.
Potentially, one could write its own set of smart contracts that pass to each other the current call stack size and then use this information to perform some call stack attacks, as suggested in the solidity documentation and in the previously mentioned paper.