Solidity Inline Assembly
Inline assembly is Yul code written inside a Solidity function. It gives direct control over memory and storage at the cost of Solidity's safety checks.
Assembly writes and reads a memory scratch area
Mstore writes a value to memory and mload reads it back. The value read back matches the value written.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract MemoryScratch {
function storeAndLoad(uint256 v) public pure returns (uint256 loaded) {
assembly {
mstore(0, v)
loaded := mload(0)
}
}
}
Assembly writes and reads a storage slot
Sstore writes a value to storage and sload reads it back. The public getter and the assembly read agree on the stored value.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract AssemblyStore {
uint256 public stored;
function setViaAssembly(uint256 v) public {
assembly {
sstore(0, v)
}
}
function getViaAssembly() public view returns (uint256 result) {
assembly {
result := sload(0)
}
}
}
Assembly addition wraps where plain Solidity reverts
Plain Solidity checks addition and reverts on overflow. Assembly addition has no such check and wraps around instead.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract CheckedVsUnchecked {
function addPlain(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
function addAssembly(uint256 a, uint256 b) public pure returns (uint256 result) {
assembly {
result := add(a, b)
}
}
}
Example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract AssemblyCounter {
uint256 public count;
function bump() public {
assembly {
let current := sload(0)
sstore(0, add(current, 1))
}
}
function bumpBy(uint256 n) public {
assembly {
let current := sload(0)
sstore(0, add(current, n))
}
}
function readViaAssembly() public view returns (uint256 result) {
assembly {
result := sload(0)
}
}
}
Key points
- Inline assembly: Inline assembly is Yul code written inside a Solidity function.
- Memory scratch: A memory scratch area is temporary memory a function can write to and read back.
- Storage slot: A storage slot is one unit of a contract's lasting storage.
- Mstore: Mstore is the Yul operation that writes a value to memory.
- Mload: Mload is the Yul operation that reads a value from memory.
- Restatement: Inline assembly trades Solidity's safety checks for direct control over memory and storage.
In this example, bump reads the counter with sload, adds one, and writes it back with sstore. BumpBy does the same with a chosen amount. ReadViaAssembly reads the counter with sload and its result matches the public getter.
Note
Assembly bypasses Solidity's safety checks, so a mistake in assembly is not caught by the compiler.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Remix IDE
Exercise
What happens when assembly addition overflows?