9

In the Solidity documentation, the definition of calldataload is:

calldataload(p) call data starting from position p (32 bytes)

But I am really confused by what is call data. Is the call data of the previous transaction or of the current call?

Say if we have a smart contract, we called method1, and then call method2 which contains assembly with calldataload. Will this calldataload load the input of method2 or method1?

1
  • thank you for answering, it is clearer now.
    – UncleJ
    Feb 28, 2019 at 21:31

1 Answer 1

6

From the docs:

calldata is a special data location that contains the function arguments, only available for external function call parameters.

Every reference type, i.e. arrays and structs, has an additional annotation, the “data location”, about where it is stored. There are three data locations: memory, storage and calldata. Calldata is only valid for parameters of external contract functions and is required for this type of parameter. Calldata is a non-modifiable, non-persistent area where function arguments are stored, and behaves mostly like memory.

Put simply, calldata is the input data to a transaction on a function. For example, if you look at this transaction, you will see that the calldata is as follows:

0x51d0eac4000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f32833125eed6d3b7fbccdcf38139967d4034ba100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000011c37937e08000

Say if we have a smart contract, we called method1, and then call method2 which contains assembly with calldataload. will this calldataload load the input of method2 or method1?

If those two method calls are different, then the calldata for each transaction will be different. The calldata for method1() will simply be the input params (in the format seen above) for that method, and the calldata for method2() will simply be the input params for that method.

If the two methods interact on the contract, whichever method is called in the transaction will be the method whose calldata is used and persists throughout the transaction.


Edit, based on flygoing's comment:

calldataload will load different data depending on the call frame, and will persist for an individual call frame, but not to the next call frame. E.g. if EOA calls function a on contract A, and contract A calls function b on contract B, the calldataload will no longer load the EOA's call data and will instead load the data used in the sub-call frame.

3
  • 3
    "calldata is used and persists throughout the transaction" - I think I know what you meant here, but this is msleading. calldataload will load different data depending on the call frame, and will persist for an individual call frame, but not to the next call frame. E.g. if EOA calls function a on contract A, and contract A calls function b on contract B, the calldataload will no longer load the EOA's call data and will instead load the data used in the sub-call frame.
    – natewelch_
    Feb 28, 2019 at 17:11
  • I see. I will update the answer accordingly. If function a on contract A calls function b on contract A, the calldataload will still be the EOA's call data, correct? Mar 1, 2019 at 19:44
  • 2
    It depends how it's called, either through a jump (local call, i.e. just doing b()) or through a message call (message call, i.e. this.b(). The latter, in Solidity, will change the calldataload, but the former wont. In Vyper, AFAIK, all calls to local functions (i.e. both this.b() and b()) create a message call so calldataload will change.
    – natewelch_
    Mar 1, 2019 at 22:05

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.