I recently got to know about the new programming language called Huff. Huff is a low-level language to write EVM smartcontracts.
What makes it different from other languages is that in Hufff we code directly in opcodes. With Huff one can write more optimized smartcontracts, as It doesn’t abstract anything from the devs and gives complete control over the stack.
I’m learning huff to get to know more about the EVM. Huff’s official Twitter has recently started posting challenges. I’ll try to solve them and document it here :).
As the challenge description says, the target is to write as little huff code as possible to return the current block number.
//[blockNumber] 0x00 //[0x00, blockNumber] mstore //saves blockNumber to mem offset 0x00 // 0x20 //[0x20] 0x00 //[0x00] return //returns }number
Huff code always starts from the
takes(0) returns(0) means that this macro doesn’t take any data from the stack and doesn’t push any data to the stack upon completion.
The following snippet gets the block number and saves it to memory at offset 0.
number 0x00 mstore
NUMBER opcode is executed, which pushes the current block number to the stack.
The goal is to return the block number. To return any data,
RETURN opcode should be used. The
RETURN opcodes take inputs only from the memory, so the block number should be stored in the memory.
0x00 which pushes 0 to the stack. So the stack looks like [0x00, blockNumber].
MSTORE opcode stores the data (block number in this case) to the memory. It takes 2 inputs,
- The memory offset,
- The data to store.
Here, 0x00 is the memory offset and block number is the data. When
MSTORE opcode is pushed to the stack, It saves the block number to the memory at offset 0.
RETURN the Block Number
As mentioned before, The
RETURN opcode is used to return the data.
0x20 0x00 return
RETURN takes 2 inputs,
- The memory offset to start reading from,
- The size in bytes.
First, the byte size 0x20 (32 bytes) is pushed into the stack. Followed by the memory offset 0x00.
The stack now looks like, [0x00, 0x20]
RETURN opcode is then pushed to the stack, which reads 32 bytes (0x20) starting from the memory offset 0 and returns it.