Cover photo

Intro to Transient Storage at Bytecode Level

filosofiacodigo.eth

filosofiacodigo.eth and Cooldev1337

We reject abstraction
We believe in bytecode
Bytecode is only true form
Let’s code with bytes now

Last week, we dissected smart contract deployment and how to separate init code from runtime code.

This week, we're diving into a recent (Dencun update) and powerful EVM feature: Transient Storage.

Why Do We Need Transient Storage?

We already know the three main data regions in the EVM: the stack which is super fast but only lasts for the current instruction, the memory that resets after each all and the persistent storage.

But there’s a gap:
What if we want to share temporary data between cross contract calls in a single transaction. Specifically in cases where data doesn’t need to persist after the transaction ends.

That’s where Transient Storage comes in.

What Is Transient Storage?

Transient Storage is like ephemeral memory that survives across calls but gets wiped at the end of the transaction. It’s a key-value store like regular SSTORE, but it’s cheaper and isolated to the current transaction.

The Opcodes: TSTORE and TLOAD

Ethereum introduced two new opcodes (with EIP-1153 in Decun update) to interact with transient storage:

Opcode

Name

Description

5C

TLOAD

Load a value from transient storage

5D

TSTORE

Store a value into transient storage


These behave exactly like SLOAD and SSTORE, except the data is not persistent and can be use across smart contract calls.

Example:

Imagine a contract where Contract A sets a flag, calls Contract B, B calls A again, and then A checks that flag. With transient storage, Contract A can do this without writing to permanent storage.

Here’s a simplified outline:

PUSH1 0x01		// Value to write
PUSH1 0x00		// Key to write
TSTORE				// Store 1 into transient[0]

CALL					// Call logic (Abstracted because have not discussed it here yet)


// Reentry point
PUSH1 0x00		// Key to read
TLOAD				// Read from transient[0]

Unlike memory (which resets when there is an external call), this value remains accessible to all internal functions during the transaction.

post image
Step by step animation of TSTORE and TLOAD usage

Hands-On: Transient vs Persistent

Let’s store and retrieve a value both in transient and persistent storage to compare:

// Transient Store
PUSH1 0x2A
PUSH1 0x00
TSTORE
// Transient Load
PUSH1 0x00
TLOAD
// Persistent Store
PUSH1 0x2A
PUSH1 0x01
SSTORE
// Persistent Load
PUSH1 0x01
SLOAD

As you can see, the call API is very similar but when the transaction ends, the persistent value at slot 0x01 remains on-chain while the transient value at slot 0x00 is gone.

Use Cases for Transient Storage

  • Re-entrancy Guards: Instead of storing a boolean in storage (expensive), store a flag in transient storage.

  • Efficient Intermediate Values: Use transient slots to coordinate between multiple contract calls without touching global state nor calldata parameters.

  • Gas-Efficient Caching: Cache data temporarily across contract calls in the same transaction.

Visual Recap

Region

Lifetime

Access Pattern

Gas Cost

Shared Across Calls?

Stack

One operation

LIFO

Very low

No

Memory

One transaction (until there is a call)

Byte offset

Low

No

Storage

Forever

Key-value

High

Yes

Transient

One transaction

Key-value

Low-medium

Yes

Try It Yourself

Write and check using this EVM Disassembler bytecode that:

  1. Stores 0xAA in transient slot 0x00

  2. Loads it from the same slot

  3. Returns it

We’ve now seen how to manage state across contract calls, next Tuesday, we’ll look at how contracts organize their dispatch logic using functions. Subscribe for more bytes.

Intro to Transient Storage at Bytecode Level