Cover photo

What is an Opcode?

filosofiacodigo.eth

filosofiacodigo.eth and Cooldev1337

We reject abstraction
We believe in bytecode
Bytecode is the only true form
Let’s code with bytes now

Welcome back to Bytecode Tuesday🤝

Last week, we talked about EVM Bytecode, the raw machine level code that the Ethereum Virtual Machine (EVM) understands and executes. This week, we're going a level deeper: Opcodes.

What is an Opcode?

An opcode (short for operation code) is a single instruction that tells the EVM what to do.

Think of it like a Lego block: each opcode does one very specific thing. When you put a bunch of them together, you build a working smart contract.

Each opcode is represented by 1 byte (2 hexadecimal characters), and each one corresponds to an operation like:

Storing data Loading data Adding two numbers Returning a result Jumping to a different part of the code

Some opcodes are followed by parameters or data, depending on what the operation needs.

Let's look at real Bytecode

Let’s take this snippet of bytecode:

7F00000000000000000000000000000000000000000000000000000000000000105F5260205FF3

What does this program do?

In plain English:

It pushes the number 16 (at the end of the PUSH32) to memory position 0 Then, it returns 32 bytes of memory starting at position 0 This includes the number 16 we just stored, followed by 31 zero bytes

It's a simple program that always returns the same 32-byte value (number 16 in decimal), which is composed mostly of zeros, except for a 0x10 (16) at the end.

We’ll break this down into opcodes and understand what each one does.

Dissecting the Code

We'll read it left to right, 1 byte at a time (2 hex characters = 1 byte)

post image
Bytecode is interpreted left to right, 1 byte (2 hex characters) at a time

Initial Stack: The stack is empty at the beginning.

post image

Opcode 7F (PUSH32): Pushes the next 32 bytes onto the stack. These bytes represent the number 0x0000000000000000000000000000000000000000000000000000000000000010, which is 16 in decimal.

post image

Opcode 5F (PUSH0): Pushes the constant 0 onto the stack (Equivalent to PUSH1 0, but with gas savings).

post image

Opcode 52 (MSTORE): Pops the top two values from the stack and stores the second value at the memory location specified by the first value. In this case, it stores 0x0000000000000000000000000000000000000000000000000000000000000010 at memory location 0.

post image

Opcode 60 20 (PUSH1 0x20): Pushes the byte 0x20 (32 in decimal) onto the stack (length of the data we want to return).

post image

Opcode 5F (PUSH0): Pushes the constant 0 onto the stack.

post image

Opcode F3 (RETURN): Pops the top two values from the stack. The first value specifies the memory location to start returning data from, and the second value specifies the size of the data to return. It returns 32 bytes starting from memory location 0.

post image

The returned data is 0x0000000000000000000000000000000000000000000000000000000000000010, the number 16 in decimal notation.

Understanding the Flow

Stack Operations: The stack operates on a Last In, First Out (LIFO) principle. Each opcode manipulates the stack by pushing or popping values, which are then used in subsequent operations.

Memory Storage: The MSTORE opcode stores data in memory, which is temporary and used during contract execution. In this example, the number 16 is stored at memory location 0.

Returning Data: The RETURN opcode allows the contract to return data to the caller. It specifies the memory location and size of the data to be returned.

Assignment

Try using our online EVM Disassembler to break apart this bytecode yourself.

What is an Opcode?