EVM opcode
An opcode is one single instruction the Ethereum Virtual Machine knows how to perform, like ADD two numbers, store a value, or call another contract. Picture the EVM as a very simple calculator that reads a long ribbon of bytes one at a time; each byte it reads is an opcode telling it exactly what to do next. There are roughly 140 of them, and every smart contract that has ever run is ultimately just a sequence of these tiny commands.
Each opcode is encoded as a single byte, so the value space runs from 0x00 to 0xFF. They group into families: arithmetic and comparison (ADD 0x01, MUL 0x02, LT 0x10), bitwise logic (AND, OR, XOR), environment and block context (CALLER 0x33, TIMESTAMP 0x42), stack/memory/storage moves (MLOAD 0x51, SSTORE 0x55), control flow (JUMP 0x56, JUMPI 0x57), logging (LOG0–LOG4), and system calls (CALL 0xF1, CREATE 0xF0, REVERT 0xFD). The PUSH family (PUSH1 0x60 through PUSH32 0x7F, plus PUSH0 0x5F added in Shanghai) are special: they are the only opcodes that carry inline immediate data, embedding the constant to be pushed directly in the bytecode after the opcode byte.
The EVM is a stack machine, so almost every opcode works by popping its inputs off the top of the stack and pushing its result back. ADD pops two words and pushes their sum; SSTORE pops a key and a value and writes to persistent storage, pushing nothing. Crucially, each opcode also has a fixed or formula-based gas cost — arithmetic is cheap, storage writes are very expensive — which is how the protocol meters and bounds every computation.
Opcodes are the bedrock contract that the Ethereum protocol promises every client must implement identically. If two clients disagreed on what even one opcode does, they would compute different state roots and the chain would split. That is why opcode semantics are specified to the bit in the Yellow Paper and changes (adding PUSH0, repricing SLOAD) require careful, coordinated hard forks.
PUSH1 0x03 // stack: [3] PUSH1 0x02 // stack: [2, 3] ADD // stack: [5]
A minimal opcode sequence; PUSH carries its operand inline, ADD consumes two stack words.
Not every byte from 0x00–0xFF is assigned; unassigned values are 'invalid' opcodes that immediately abort execution and consume all remaining gas, which is different from an orderly REVERT.