1

I try to understand how CALLDATACOPY works.

destOffset: byte offset in the memory where the result will be copied.

offset: byte offset in the calldata to copy.

size: byte size to copy.

I try to execute the following opcodes

caldata is 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

PUSH1 4

PUSH1 31

PUSH1 0

CALLDATACOPY

result is ff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Could you explain where the offset and size are in this result ?

1 Answer 1

5

According to EVM opcode description:

Note: the below is written in kind of python array slicing convention: array starts at index 0 and array[0:2] means the array[0] and array[1] elements (not including the array[2] element):

CALLDATACOPY  Stack (from top to bottom): destOffset | offset | length  
=> memory[destOffset:destOffset+length] = msg.data[offset:offset+length]

When you reach CALLDATACOPY, your stack is 0 => 31 => 4 which means:

  1. destOffset = 0
  2. offset = 31
  3. length = 4

This one copies 4 bytes from the calldata from the 31th byte to write to memory at location 0. Because your calldata only has 32 bytes 0xff.....ff so it copies only the last 0xff and fill the rest with 0x00,0x00,0x00 and write to memory at location 0.

So the final memory at location 0: 0xff000000... the rest is the memory before the call to CALLDATACOPY I guess.

Test contract with the same sequence of opcode, call it with your calldata:

contract Test{
    fallback() external {
        assembly {
            calldatacopy(0, 31, 4)
        }
    }
}

--- Update: another example : When you reach CALLDATACOPY, your stack is 0 => 29 => 3 which means:

  1. It's equivalent to calldatacopy(0, 29, 3) in the above test contract
  2. destOffset = 0 ; offset = 29 ; length = 3
  3. Call data is : 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAABBCCDDEE
  4. 0th byte 0xff | 1st byte 0xff | .... | 28th byte 0xBB | 29th byte : 0xCC | ...
  5. memory[0,3] = 0xcc 0xdd 0xee....
2
  • I start with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAABBCCDDEE and I write the following opcodes PUSH1 3 PUSH1 29 PUSH1 0 CALLDATACOPY result is ccddee0000000000000000000000000000000000000000000000000000000000 is this correct in your logic? Commented Jan 10, 2023 at 12:58
  • 1
    I updated the answer, please take a look.
    – minhhn2910
    Commented Jan 10, 2023 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.