### Using Assembly in Solidity.
When developing smart contracts in Solidity, you’re working with a high-level language designed to abstract away Ethereum Virtual Machine (EVM) internals. But sometimes, to gain more control, optimize gas usage, or perform low-level operations, you need to drop down a level — that’s where **Yul**, Solidity’s assembly language, comes into play.
**What Is Yul?**
Yul is an intermediate(sir btw assembly and solidity), low-level language designed to be compatible with multiple backends like the EVM and eWASM. It acts as a bridge between high-level Solidity code and the machine-level bytecode executed on-chain.
**Why Use Yul (Assembly)?**
While you rarely need to use assembly, there are valid use cases:
- *Gas Optimization:* Some operations can be done cheaper using low-level instructions.
- *Direct Memory Manipulation:* Working with memory/storage in custom ways.
- *Custom Functionality:* Accessing EVM opcodes not exposed in Solidity.
- *Fallback Functions:* Writing minimal proxy contracts or upgradeable patterns.
**Basic Yul Syntax**
Here’s a minimal example of using Yul inside Solidity:
```solidity
pragma solidity ^0.8.28;
contract Yul{
function add(uint x, uint y) public pure returns (uint z) {
assembly {
z := add(x, y)
}
}
}
```
Here, the *assembly {}* is a Yul block, and add(x, y) uses the EVM’s ADD opcode directly.
**Memory and Storage in Yul**
Yul allows low-level access to memory and storage:
```solidity
assembly {
mstore(0x0, 42) // store 42 at memory slot 0
let value := mload(0x0) // read from memory slot 0
}
```
- `mstore(offset, value)` – store in memory
- `mload(offset)` – load from memory
- `sstore(slot, value)` – store in storage
- `sload(slot)` – load from storage
**Control Structures in Yul**
Yul supports `if`, `switch`, `for`, and `function`:
```solidity
assembly {
if eq(x, 5) {
y := 10
}
for { let i := 0 } lt(i, 10) { i := add(i, 1) } {
// loop logic
}
function square(val) -> result {
result := mul(val, val)
}
}
```
**Calling Functions and Contracts in Yul**
Example of a low-level call:
```solidity
assembly {
let success := call(gas(), target, 0, inputPtr, inputSize, outputPtr, outputSize)
if iszero(success) {
revert(0, 0)
}
}
```
This is useful in proxy patterns or when creating custom call behaviors.
**Final Note**
Yul opens the door to mastering the EVM and optimizing Solidity at a deep level. While it’s not always necessary, knowing how to drop into assembly can give you an edge in performance-critical scenarios or advanced contract design like proxies or custom libraries. Using Assembly in Solidity is want superpower you want to use with caution.