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?

0

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. Commented 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? Commented 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. Commented Mar 1, 2019 at 22:05

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.