What you've got in bytecode here is the contract's constructor / construction bytecode. When you create a contract, the constructor runs, handles any initial arguments or statements you make, and also "creates" the code of the contract.
The way this is done is through a return statement. The deployed contract code will be whatever the constructor returns. So the bytecode you posted will include the bytecode of the constructor, as well as the code of the deployed contract itself. It also includes a third section - some metadata (a Solidity feature). Breaking it down, here are the 3 distinct sections:
Constructor bytecode (basically a deployment script):
0x6080604052348015600f57600080fd5b50603580601d6000396000f300
This translates to the following opcodes, which I've annotated a bit:
// Set free memory pointer (0x40) to 0x80
[1] PUSH1 0x80
[3] PUSH1 0x40
[4] MSTORE
// Check msg.value
[5] CALLVALUE
[6] DUP1
[7] ISZERO
// If msg.value == 0, JUMP to 0x0F (15)
[9] PUSH1 0x0f
[10] JUMPI
// Otherwise, the next 3 instructions do: revert(0, 0)
[12] PUSH1 0x00
[13] DUP1
[14] REVERT
// Here's 0x0F, which has a corresponding JUMPDEST
[15] JUMPDEST
[16] POP
// Now we need the constructor to set up the deployment bytecode:
// 0x35 is presumably the length of the bytecode to return
[18] PUSH1 0x35
[19] DUP1
// 0x1D is the location in the bytecode from which the CODECOPY starts (29)
[21] PUSH1 0x1d
// 0x00 is where the code is copied to, in memory
[23] PUSH1 0x00
[24] CODECOPY
// Now we have the bytecode of the contract in memory, starting at 0x00 (and 0x35 bytes long). We DUP1'd the length earlier, so we can just push 0x00 and RETURN. The RETURN opcode will return 0x35 bytes, starting at position 0x00 in memory.
[26] PUSH1 0x00
[27] RETURN
[28] STOP
// A final STOP at 28 (0x1C) marks the end of the constructor bytecode. The code copied started at 0x1D, so the next chunk of bytecode will be the deployed code
And now here's the contract bytecode (with metadata at the end):
0x6080604052600080fd00a165627a7a7230582053a24015f887e1dd9fbd5e5cadb397bb5fb34e8aab7b5782d9e28dfd4e9862810029
Again, translated to opcodes:
// Set free memory pointer (0x40) to 0x80
[30] PUSH1 0x80
[32] PUSH1 0x40
[33] MSTORE
// The next 3 opcodes simply push 0 twice, then REVERT(0, 0)
[35] PUSH1 0x00
[36] DUP1
[37] REVERT
// And, a final STOP to mark the end of contract bytecode!
[38] STOP
// This next bit is confusing when translated directly from opcodes, because it's simply the metadata Solidity appends to the end of bytecode. It's not meant to be executed
[39] LOG1
[46] PUSH6 0x627a7a723058
[47] SHA3
[48] MSTORE8
[49] LOG2
[50] BLOCKHASH
[51] ISZERO
[52] 'f8'(Unknown Opcode)
[53] DUP8
[54] 'e1'(Unknown Opcode)
[55] 'dd'(Unknown Opcode)
[56] SWAP16
[57] 'bd'(Unknown Opcode)
[58] '5e'(Unknown Opcode)
[59] '5c'(Unknown Opcode)
[60] 'ad'(Unknown Opcode)
[61] 'b3'(Unknown Opcode)
[62] SWAP8
[63] 'bb'(Unknown Opcode)
[64] '5f'(Unknown Opcode)
[65] 'b3'(Unknown Opcode)
[66] '4e'(Unknown Opcode)
[67] DUP11
[68] 'ab'(Unknown Opcode)
Here's more information on contract metadata: https://solidity.readthedocs.io/en/v0.4.24/metadata.html
So, to directly answer your questions:
Yes, this is meant to be the constructor bytecode. Since the constructor needs to return the deployment bytecode, the constructor bytecode includes the deployment bytecode as well.
The sequences to which you are referring are from the contract's metadata, and are not meant to be executed.
The contract you compiled doesn't have any functions, so the entirety of the "runtime bytecode" is the 10-opcode section of the deployed bytecode, which sets the free memory pointer and immediately reverts. A typical contract with functions will do something slightly different -- it will grab the first 4 bytes of calldata (using CALLDATALOAD
), and compare those against a series of function selectors. When it finds a match, it will JUMP
to that function's position in the code. If no match is found, it executes the fallback function. If that doesn't exist, it reverts!
Hope that cleared it up! Feel free to ask more questions!