2

I've been reading this example from https://github.com/comaeio/porosity/wiki/Ethereum-Internals

And I am wondering how some of these JUMPI operations are valid:

loc_00000000:
0x00000000 60 60                      PUSH1 60 
0x00000002 60 40                      PUSH1 40 
0x00000004 52                         MSTORE 
0x00000005 60 e0                      PUSH1 e0 
0x00000007 60 02                      PUSH1 02 
0x00000009 0a                         EXP 
0x0000000a 60 00                      PUSH1 00    
0x0000000c 35                         CALLDATALOAD 
0x0000000d 04                         DIV 
0x0000000e 63 06  72  e9  ee          PUSH4 06 72 e9 ee 
0x00000013 81                         DUP2 
0x00000014 14                         EQ 
0x00000015 60 24                      PUSH1 24 
0x00000017 57                         JUMPI 

loc_00000018:
0x00000018 80                         DUP1 
0x00000019 63 9d  04  0a  f4          PUSH4 9d 04 0a f4 
0x0000001e 14                         EQ 
0x0000001f 60 35                      PUSH1 35 
0x00000021 57                         JUMPI 

loc_00000022:
0x00000022 5b                         JUMPDEST 
0x00000023 00                         STOP 

double(uint256):
0x00000024 5b                         JUMPDEST 
0x00000025 60 45                      PUSH1 45 
0x00000027 60 04                      PUSH1 04 
0x00000029 35                         CALLDATALOAD 
0x0000002a 60 00                      PUSH1 00 
0x0000002c 60 4f                      PUSH1 4f 
0x0000002e 82                         DUP3 
0x0000002f 60 02                      PUSH1 02 

loc_00000031:
0x00000031 5b                         JUMPDEST 
0x00000032 02                         MUL 
0x00000033 90                         SWAP1 
0x00000034 56                         JUMP 

triple(uint256):
0x00000035 5b                         JUMPDEST 
0x00000036 60 45                      PUSH1 45 
0x00000038 60 04                      PUSH1 04 
0x0000003a 35                         CALLDATALOAD 
0x0000003b 60 00                      PUSH1 00 
0x0000003d 60 4f                      PUSH1 4f 
0x0000003f 82                         DUP3 
0x00000040 60 03                      PUSH1 03 
0x00000042 60 31                      PUSH1 31 
0x00000044 56                         JUMP 

For example, at address 0x18, the first stack item is duplicated, which i believe is 24. Following this, at address 0x19, 9d 04 0a f4 is pushed to the stack. An equality comparison is then made at address 0x1e, and if true this will jump to address 0x35. However, I believe that this is not valid as 24 and 9d 04 0a f4 are not equal. So how is this jump valid? Thanks

2

When address 0x18 is reached, the stack top does not contain 0x24. 0x24 was pushed earlier and is the target of JUMPI, along with another operand, the result of EQ. No matter whether the branch is taken, JUMPI pops 2 operands (and jumps or falls-through to the next instruction).

At this point, when DUP1 is executed, the top of the stack contains the function selector retrieved by CALLDATALOAD earlier. And another comparison against teh constract's public methods' selectors takes place.

That is made via the classic stub:

...
DUP1 // where top of stack is the function sel.
PUSH SELECTOR_OF_METHOD_X
EQ
PUSH ADDRESS_METHOD_X
JUMPI

DUP1 // where top of stack is the function sel.
PUSH SELECTOR_OF_METHOD_Y
EQ
PUSH ADDRESS_METHOD_Y
JUMPI
...

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.