You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pragma solidity ^0.4.11;
contract Simple {
bytes32 public v;
function set(bytes32 _v) {
v = _v;
}
}
interpretation of disassembly
opcodes have been inserted at line starts
goeth evm cmd compiler seems not to accept 0x values nor push# instructions, so values have been converted to decimal and instruction replaced with push
invalid opcode is not understood by go-eth evm cmd
///////////////////////////////////////
// PART 1
// contract creation part
// store 0x60 at 0x40+0x1f
// this is the memory storage offset
// see https://ethereum.stackexchange.com/a/2829/5711 for quick and simple explanation
60 push 96 // (0x60)
60 push 64 // (0x40)
52 mstore
// if there is eth sent with this transaction
// if not, jump to PART 2
34 callvalue
15 iszero
60 push 15 // (61 push2 0x000f)
57 jumpi
60 push 00
80 dup
// (not implemented in go-eth evm cmd)
// maybe see https://github.com/ethereum/go-ethereum/issues/14376
fd invalid
5b jumpdest
///////////////////////////////////////
// PART 2
// copy 218 bytes from code pos 30 to mem pos 0
// this is presumably contract constructor?
5b jumpdest
60 push 218 // (0xda)
80 dup1
61 push 30 // (61 push2 0x001e), why is this push2?
60 push 0
39 codecopy
// return 218 bytes from mem pos 0
60 push 00
f3 return
00 stop
///////////////////////////////////////
//
// WARNING!
// instruction byteaddresses from here on
// are from the RUNTIME binary
//
///////////////////////////////////////
///////////////////////////////////////
// PART 3
// this is the actual contract
// the "runtime binary" starts here
60 push 96 (0x60)
60 push 64 (0x40)
52 mstore
// call calldata from pos 0
// this is function name digest
// divide it by 2^(8*29), which removes the trailing 0's
// then AND with all 1's (to make sure the length of the data is ok?)
60 push 00
35 calldataload
60 push 26959946667150639794667015087019630673637144422540572481103610249216 // (7c push29 0100000000000000000000000000000000000000000000000000000000)
90 swap1
04 div
60 push 4294967295 (63 push4 ffffffff)
16 and
// if callvalue matches the "v()" function
// jump to PART 4
80 dup1
60 push 2083454138// (63 push4 0x7c2efcba)
14 eq
60 push 71 //(0x47)
57 jumpi
// if callvalue matches the set(bytes32) function
// jump to PART 6
80 dup1
60 push 3682631999 (63 push4 0xdb80813f)
14 eq
60 push 117 // (0x75)
57 jumpi
5b jumpdest
60 push 00
80 dup1
fd invalid
///////////////////////////////////////
// PART 4
// entrypoint for v()
// if any eth is sent with the call
// pass through and fail
5b jumpdest
34 callvalue
15 iszero
60 push 81 // (0x51)
57 jumpi
60 push 00
80 dup1
fd invalid
// jump to PART 8
// the 0x57 is return jump address (PART 5)
5b jumpdest
60 push 87 // (0x57)
60 push 153 // (0x99)
56 jump
///////////////////////////////////////
// PART 5
// returns the v member we retrieved in PART 8
// retrieves the safe memory position from 0x40 (which is 0x60)
// stores the value there
// calculates the length of the data to be returned and offset
// returns
5b jumpdest
60 push 64 // (0x40)
51 mload
80 dup1
82 dup3
60 push 00
19 NOT
16 AND
60 push 00
19 NOT
16 AND
81 dup2
52 MSTORE
60 push 32 //(0x20)
01 add
91 swap2
50 pop
50 pop
60 push 64 //(0x40)
51 mload
80 dup1
91 swap2
03 sub
90 swap1
f3 return
///////////////////////////////////////
// PART 6
// entrypoint for set(byte32)
// if any eth is sent with the call
// pass through and fail
5b jumpdest
34 callvalue
15 iszero
60 push 127 // (0x7f)
57 jumpi
60 push 00
80 dup1
fd invalid
// set return jump position after PART 9
// (151 is the position of PART 7)
5b jumpdest
60 push 151 // (0x97)
60 push 04
80 dup1
// get (32 bytes) calldata at pos 0x4
// which is after the function digest part
// thus our first and only argument
// todo: does the popped data serve any function here?
80 dup1
35 calldataload
60 push 00
19 not
16 and
90 swap1
60 push 32 (0x20)
01 add
90 swap1
91 swap2
90 swap1
50 pop
50 pop
// input value is now on top of stack
// jump to PART 9
60 push 159 //(0x9f)
56 jump
///////////////////////////////////////
// PART 7
// the set(bytes32) method stops here
5b jumpdest
00 stop
///////////////////////////////////////
// PART 8
// get the v member of contract
// retrieve stored value at 0
// then jump back to part 5
5b jumpdest
60 push 00
54 sload
// jump to PART 5
// (the dup2 copies the push 0x57 from the end of PART 4 to the stack top)
// after this jump the value of v will be on the top of the stack
81 dup2
56 jump
///////////////////////////////////////
// PART 9
// set the v member
// the input value is on top of stack
5b jumpdest
80 dup1
60 push 00
81 dup2
60 push 00
19 not
16 and
90 swap1
55 sstore
50 pop
5b jumpdest
// jump to PART 7
// (remix debugger says stack[0] here is 0x97)
50 pop
56 jump
00 stop
/////////////////////////
// PART 10
// the remaining bytecode is metadata
// see http://solidity.readthedocs.io/en/develop/miscellaneous.html#contract-metadata
// a165627a7a7230582042d3fc516aa5c0d6c9cf48399e78cfae9270c79071086c71049c2fb3b23603640029
// cbor encoing of swarm hash 42d3fc516aa5c0d6c9cf48399e78cfae9270c79071086c71049c2fb3b2360364
bytecode and disassembly of contract binary (go-eth evm cmd)