A simple Huff Program to Determine Even Number
Huff is a domain-specific, low-level programming language designed explicitly for writing smart contracts on the Ethereum blockchain.
In this tutorial, we are writing a Huff smart contract that checks whether a given number is even or odd. The contract should return 1 if the number is even and 0 if the number is odd.
Note: For those unfamiliar with calldata, it is a type of input data sent with a transaction. Calldata is stored outside the EVM’s storage and memory, making it cheaper to use.
Basic Solution
Here’s a basic Huff contract to solve this problem:
#define macro MAIN() = takes(0) returns (0) {
0x02 //[0x02]
0x00 calldataload //[input, 0x02]
mod //[0 or 1]
iszero //[1 or 0]
0x00 mstore
0x20 0x00 return
}
Explanation
MAIN Macro
In Huff, execution always starts from the MAIN
macro. The takes(0) returns(0)
indicates that this macro doesn’t read any values from the stack and doesn’t push any value to the stack upon completion.
Logic
Push 2 to the Stack
0x02
This pushes the number 2 onto the stack.
Load Calldata
0x00 calldataload
The
calldataload
opcode loads the transaction input data to the stack. The opcode takes one argument, the offset (0x00) to start loading from.Modulus Operation
mod
The
mod
opcode takes two inputs from the stack and returns the remainder of the division. If the number is even, the result will be 0.Check if Zero
iszero
The
iszero
opcode checks if the value at the top of the stack is zero. If it is, it returns 1 (indicating the number is even); otherwise, it returns 0 (indicating the number is odd).Store Result in Memory
0x00 mstore
The
mstore
opcode stores the result at memory offset 0x00.Return Result
0x20 0x00 return
The
return
opcode returns 32 bytes from memory offset 0x00.
Optimization
While the above code does the job, there is room to save gas. Each time we push 0 onto the stack using 0x00
, Huff replaces it with the PUSH
opcode, which costs 3 gas.
The EVM wizards in the Huff Discord found another way to push 0 onto the stack using the RETURNDATASIZE
opcode, which costs only 2 gas. The RETURNDATASIZE
opcode pushes the length of the data returned in the last call. Since we haven’t made any external calls, it will push 0 onto the stack.
Optimized Solution
Here’s the optimized Huff contract:
#define macro MAIN() = takes(0) returns (0) {
0x02 //[0x02]
returndatasize calldataload //[input, 0x02]
mod //[0 or 1]
iszero
returndatasize mstore
0x20 returndatasize return
}
Optimization Steps
Push 2 to the Stack
0x02
Load Calldata with Optimized 0
returndatasize calldataload
This pushes 0 onto the stack using
RETURNDATASIZE
, saving 1 gas compared to using0x00
.Modulus Operation
mod
Check if Zero
iszero
Store Result in Memory with Optimized 0
returndatasize mstore
Return Result with Optimized 0
0x20 returndatasize return
By replacing 0x00
with RETURNDATASIZE
in three places, we save 3 gas, equivalent to one PUSH
.
Conclusion
This optimized Huff contract efficiently determines whether a given number is even or odd. By leveraging the RETURNDATASIZE
opcode, we reduce the gas consumption, making the contract more efficient.
Learn How To Build AI Projects
Now, if you are interested in upskilling in 2024 with AI development, check out this 6 AI advanced projects with Golang where you will learn about building with AI and getting the best knowledge there is currently. Here’s the link.
Last updated 17 Aug 2024, 12:31 +0200 .