5/5
## A Developer's Guide to Transient Storage in Solidity With the Ethereum Cancun-Deneb upgrade came EIP-1153, which introduced a new type of storage location for smart contracts: **transient storage**. This feature provides a powerful, gas-efficient way to manage data within the scope of a single transaction. Let's explore what it is, how it differs from traditional state storage, and why it's a game-changer for patterns like re-entrancy locks, as seen in the Uniswap v4 codebase. ### The Problem: Transaction-Scoped Data Before transient storage, developers had two primary locations to store data: state storage and memory. * **State Storage:** Extremely useful but expensive. Data written to state variables is stored permanently on the blockchain and persists across multiple transactions. This is ideal for long-term data but overkill for temporary information. * **Memory:** Cheap and fast, but its scope is limited to a single function call. Data in memory is lost when a function (including its internal calls) completes, making it unsuitable for passing information across external calls within the same transaction. This left a gap: what if you need data to persist across multiple external contract calls but only for the duration of a *single transaction*? A classic example is a re-entrancy lock. You need the lock's status to be visible to all contracts involved in the transaction, but you don't care about its value once the transaction is finalized. Using a state variable for this is inefficient and costs unnecessary gas. This is precisely the problem that transient storage solves. ### Transient vs. State Storage: The Key Differences Transient storage introduces a third data location that sits between the persistence of state storage and the ephemerality of memory. 1. **Lifecycle and Persistence:** This is the most critical distinction. Data written to transient storage is only accessible **within the current transaction**. Once the transaction is successfully mined (or fails), all transient storage slots are completely wiped clean and reset to zero. In contrast, data in state storage persists indefinitely across transactions until it is explicitly modified. 2. **Gas Costs:** Because transient storage values are discarded at the end of a transaction, they don't need to be written to the blockchain's permanent state trie. This makes operations with transient storage significantly cheaper than their state storage counterparts (`SSTORE` vs. `TSTORE`). This unique lifecycle makes transient storage perfect for two primary use cases: * **Re-entrancy Locks:** As seen in Uniswap v4, a lock can be acquired at the start of a transaction, checked during subsequent internal or external calls, and then forgotten. Transient storage provides a gas-efficient mechanism for this common security pattern. * **Passing Context for Callbacks:** When a contract calls another and expects a callback within the same transaction, transient storage can act as a temporary message bus. The initial contract can write data to a transient slot, and the contract being called (or the subsequent callback) can read that data without needing complex function parameters or expensive state variables. ### How to Use Transient Storage in Solidity Transient storage is accessed via two new opcodes, `TSTORE` and `TLOAD`, which are currently only available through inline assembly. * `tstore(slot, value)`: Stores a `value` in a given `slot`. The slot is a `bytes32` key, similar to storage slots. * `tload(slot)`: Loads the value from the specified `slot`. Let's look at a practical demonstration comparing the behavior of state and transient storage. #### Example 1: Standard State Storage This contract uses a regular `uint256` state variable. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; contract StateStorage { uint256 public val; function set(uint256 v) public { val = v; } } ``` If we call `set(1)` in one transaction, the value of `val` becomes 1. If we then start a *new transaction* and call `val()`, it will still return 1 because the data persists across transactions. #### Example 2: Transient Storage This contract uses `tstore` and `tload` to manage its data. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; contract TransientStorage { // Define a constant for our transient storage slot bytes32 constant SLOT = bytes32(0); function set(uint256 val) public { assembly { // Store the value `val` in the transient slot `SLOT` tstore(SLOT, val) } } function get() public view returns (uint256 val) { assembly { // Load the value from the transient slot `SLOT` into `val` val := tload(SLOT) } } } ``` The behavior here is completely different. 1. **Within a single transaction:** If you call `set(1)` and then call `get()` *within the same transaction*, `get()` will correctly return 1. 2. **Across separate transactions:** If you call `set(1)` in one transaction, that transaction completes. When you start a *new transaction* and call `get()`, it will return `0`. The value was discarded the moment the first transaction ended. ### Proof: A Test Walkthrough We can confirm this behavior with a simple Foundry test. Imagine the `setUp()` function is our first transaction and a separate `test_again()` function is our second. #### Test Results for `StateStorage` When testing the `StateStorage` contract, the logs would look like this: ``` Logs: --- State --- Initial get(): 0 After set(1), get(): 1 --------- In new transaction, get(): 1 <-- The value persisted! After set(2), get(): 2 ``` The value `1` from the first transaction carried over to the second one. #### Test Results for `TransientStorage` The same test performed on the `TransientStorage` contract yields a different result: ``` Logs: --- Transient --- Initial get(): 0 After set(1), get(): 1 --------- In new transaction, get(): 0 <-- The value was reset! After set(2), get(): 2 ``` As expected, when the second transaction began, the value read from the transient slot was `0`, proving that it was automatically cleared. ### Conclusion Transient storage is a powerful addition to the EVM developer's toolkit. By providing a gas-efficient data location scoped to a single transaction, it enables cleaner, cheaper, and safer implementations of common patterns like re-entrancy guards and complex multi-contract interactions. As you build or interact with modern smart contracts, understanding how and when to use transient storage will be essential for writing optimized and secure code.
With the Ethereum Cancun-Deneb upgrade came EIP-1153, which introduced a new type of storage location for smart contracts: transient storage. This feature provides a powerful, gas-efficient way to manage data within the scope of a single transaction. Let's explore what it is, how it differs from traditional state storage, and why it's a game-changer for patterns like re-entrancy locks, as seen in the Uniswap v4 codebase.
Before transient storage, developers had two primary locations to store data: state storage and memory.
State Storage: Extremely useful but expensive. Data written to state variables is stored permanently on the blockchain and persists across multiple transactions. This is ideal for long-term data but overkill for temporary information.
Memory: Cheap and fast, but its scope is limited to a single function call. Data in memory is lost when a function (including its internal calls) completes, making it unsuitable for passing information across external calls within the same transaction.
This left a gap: what if you need data to persist across multiple external contract calls but only for the duration of a single transaction? A classic example is a re-entrancy lock. You need the lock's status to be visible to all contracts involved in the transaction, but you don't care about its value once the transaction is finalized. Using a state variable for this is inefficient and costs unnecessary gas.
This is precisely the problem that transient storage solves.
Transient storage introduces a third data location that sits between the persistence of state storage and the ephemerality of memory.
Lifecycle and Persistence: This is the most critical distinction. Data written to transient storage is only accessible within the current transaction. Once the transaction is successfully mined (or fails), all transient storage slots are completely wiped clean and reset to zero. In contrast, data in state storage persists indefinitely across transactions until it is explicitly modified.
Gas Costs: Because transient storage values are discarded at the end of a transaction, they don't need to be written to the blockchain's permanent state trie. This makes operations with transient storage significantly cheaper than their state storage counterparts (SSTORE
vs. TSTORE
).
This unique lifecycle makes transient storage perfect for two primary use cases:
Re-entrancy Locks: As seen in Uniswap v4, a lock can be acquired at the start of a transaction, checked during subsequent internal or external calls, and then forgotten. Transient storage provides a gas-efficient mechanism for this common security pattern.
Passing Context for Callbacks: When a contract calls another and expects a callback within the same transaction, transient storage can act as a temporary message bus. The initial contract can write data to a transient slot, and the contract being called (or the subsequent callback) can read that data without needing complex function parameters or expensive state variables.
Transient storage is accessed via two new opcodes, TSTORE
and TLOAD
, which are currently only available through inline assembly.
tstore(slot, value)
: Stores a value
in a given slot
. The slot is a bytes32
key, similar to storage slots.
tload(slot)
: Loads the value from the specified slot
.
Let's look at a practical demonstration comparing the behavior of state and transient storage.
This contract uses a regular uint256
state variable.
If we call set(1)
in one transaction, the value of val
becomes 1. If we then start a new transaction and call val()
, it will still return 1 because the data persists across transactions.
This contract uses tstore
and tload
to manage its data.
The behavior here is completely different.
Within a single transaction: If you call set(1)
and then call get()
within the same transaction, get()
will correctly return 1.
Across separate transactions: If you call set(1)
in one transaction, that transaction completes. When you start a new transaction and call get()
, it will return 0
. The value was discarded the moment the first transaction ended.
We can confirm this behavior with a simple Foundry test. Imagine the setUp()
function is our first transaction and a separate test_again()
function is our second.
StateStorage
When testing the StateStorage
contract, the logs would look like this:
The value 1
from the first transaction carried over to the second one.
TransientStorage
The same test performed on the TransientStorage
contract yields a different result:
As expected, when the second transaction began, the value read from the transient slot was 0
, proving that it was automatically cleared.
Transient storage is a powerful addition to the EVM developer's toolkit. By providing a gas-efficient data location scoped to a single transaction, it enables cleaner, cheaper, and safer implementations of common patterns like re-entrancy guards and complex multi-contract interactions. As you build or interact with modern smart contracts, understanding how and when to use transient storage will be essential for writing optimized and secure code.
A technical introduction to transient storage in Solidity - Discover how EIP-1153 introduces a new, gas-efficient data location for data that only needs to persist for a single transaction. Learn how `tstore` and `tload` work and why they are ideal for patterns like re-entrancy locks.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 Singleton architecture
Uniswap v4 flash accounting
Uniswap v4 operations
Uniswap v4 lifecycle
How to build a Uniswap v4 swap router
Last updated on September 22, 2025
Duration: 5min
Duration: 7min
Duration: 39min
Duration: 35min
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 Singleton architecture
Uniswap v4 flash accounting
Uniswap v4 operations
Uniswap v4 lifecycle
How to build a Uniswap v4 swap router
Last updated on September 22, 2025