10

For those keeping track at home, the function hash of a function named ccccvKygDv() is 0xffffffff, the same as a null address.

pragma solidity ^0.4.0;

contract NullFunction {
  function ccccvKygDv() public pure { }
}

contract NormalFunction {
  function NothingWrongHere() public pure { }
}

When I look at the opcodes of the two functions listed above, I get:

NothingWrongHere()

47 PUSH4 0xffffffff
52 AND
53 DUP1
54 PUSH4 0xb1f6260f

ccccvKygDv()

47 PUSH4 0xffffffff
52 AND
53 DUP1
54 PUSH4 0xffffffff

It looks like the data being pushed to the stack will overwrite some of the data needed for the function itself.

Is this a silly question? Absolutely, but I'm asking it so that I can understand how contracts work on the opcode level a bit better.

  • "the same as a null address" What do you mean by "a null address"? Are you sure 0xffffffff isn't just a bit mask? I'd need to see more of the assembly, but that would be my first guess. – user19510 Mar 21 '18 at 2:38
  • @smarx sorry, it's not a null address (I think), but the largest value a uint of this size can hold. I'm trying to understand if the function hash having this signature will/will not cause any problems and why. Here is a gist with the full opcodes. – Hooked Mar 21 '18 at 2:48
  • I believe my guess was correct. It's just a bit mask used to extract the first four bytes of the call data. (See my answer.) – user19510 Mar 21 '18 at 2:52
7

I believe this is just a bit mask.

The code loads the call data, shifts it to the right, and then does a bitwise AND with 0xFFFFFFFF to get the (now) bottom four bytes (the function selector).

Then it compares the four bytes extracted with the known function selector. It doesn't matter that the function signature you're looking for happens to be 0xFFFFFFFF.

  • Thanks, this makes sense why it wouldn't cause a problem. What's the point of the bitwise AND though to get the function signature -- isn't it already been pushed onto the stack from CALLDATALOAD? – Hooked Mar 21 '18 at 3:03
  • 1
    CALLDATALOAD has more than just four bytes in it. The AND extracts the first 4 bytes. E.g. 0x1234567890abcdef9876 & 0xFFFFFFFF == 0x12345678. – user19510 Mar 21 '18 at 3:15
  • A minor correction: bitwise AND with 0xFFFFFFFF will extract the last 4 bytes of a word not first. The first word of input data is divided by 0x0100000000000000000000000000000000000000000000000000000000 before the AND operation to shift the first 4 bytes to the right. – medvedev1088 Mar 22 '18 at 7:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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