I understand that if there is an external function call, it will use all 7 parameters of the call(g,a,v,in,insize,out,outsize)
. However, I got a question I know low-level transfers like .transfer() will also use the instruction call(g,a,v,in,insize,out,outsize)
, if wei > 0, I can treat it as transfers, does that make sense? Meanwhile, should there still be 7 parameters for the instruction call
?
1 Answer
CALL
can be used for multiple purposes: mainly function calls and variants of sending ethers: transfer
payable
and call
.
To distinguish between function calls and ether transfer, the simplest way is to check if the input data is blank (the 4th item from the stack's top means input length so it's zero). If the CALL
is sending ether it has zero input length. Otherwise, the length of the input follows abi encoding (e.g. 4 bytes if calling function without argument)
I used the ethervm.io annotation for the above :
Opcode CALL
Stack : gas | addr | value | argsOffset | argsLength | retOffset | retLength
- Value > 0 is not an indicator of transfer because it can be a call to
payable
function in the external contract (when argsLength > 0). - With
argsLength == 0
, to distinguished between different variants of sending ethers, you can look at the gas forwarded (the first item from the stack). If it's0x8fc
, it's probablytransfer
orsend
. Otherwise it's direct call. Look at this article from solidity docs for the differences between variants for sending ether
-
-
Does it answer your question?, if yes please mark it as the answer. Otherwise, you can further comment on what else do you expect from the answer. Jan 16 at 3:10