Actualites·4 min de lecture·Par Solingo

Solidity 0.8.28 Release — New Features and Breaking Changes

Solidity 0.8.28 is here with transient storage, improved error messages, and several breaking changes. Here's what every developer needs to know before upgrading.

# Solidity 0.8.28 Release — New Features and Breaking Changes

The Solidity team released version 0.8.28 in February 2026, bringing powerful new features and some breaking changes. If you're still on 0.8.26 or earlier, here's what you need to know before upgrading.

New Features

1. Transient Storage (TSTORE/TLOAD)

The biggest addition is native support for transient storage via the transient keyword. This maps to the TSTORE and TLOAD opcodes introduced in EIP-1153 (Cancun upgrade).

What is transient storage?

Transient storage exists only for the duration of a transaction. It's cheaper than SSTORE because it doesn't persist to disk.

Gas savings:

  • TSTORE: 100 gas (vs 20,000 for cold SSTORE)
  • TLOAD: 100 gas (vs 2,100 for cold SLOAD)

Use case: Reentrancy guards

// OLD: Costs ~20k gas to write, ~2.1k to read

contract OldReentrancyGuard {

bool private _locked;

modifier nonReentrant() {

require(!_locked, "Reentrant call");

_locked = true;

_;

_locked = false;

}

}

// NEW: Costs only 100 gas per read/write

contract NewReentrancyGuard {

bool private transient _locked;

modifier nonReentrant() {

require(!_locked, "Reentrant call");

_locked = true;

_;

_locked = false;

}

}

Savings: ~39,900 gas per protected function call.

Other use cases:

  • Flash loan state tracking
  • Temporary allowances
  • Atomic swap coordination
  • Cross-contract call context

Limitations:

  • Cannot be accessed after transaction ends
  • Not available in view/pure functions
  • No inheritance between contracts (each has isolated transient storage)

2. Improved Error Messages

Compiler error messages are now significantly clearer, especially for type mismatches and inheritance issues.

Before (0.8.26):

TypeError: Member "value" not found or not visible after argument-dependent lookup in address.

After (0.8.28):

TypeError: Member "value" not found in address.

Did you mean to use "address.balance"?

Suggestions: balance, call, delegatecall

This alone will save hours of debugging for beginners learning Solidity.

3. Custom Errors in Require Statements

You can now use custom errors with require:

error InsufficientBalance(uint256 available, uint256 required);

function withdraw(uint256 amount) external {

// OLD syntax (still works)

require(balance >= amount, "Insufficient balance");

// NEW syntax with custom error

require(balance >= amount, InsufficientBalance(balance, amount));

balance -= amount;

}

This gives you the gas savings of custom errors with the simplicity of require syntax.

4. Inline Assembly Improvements

New inline assembly features:

  • verbatim blocks for injecting raw bytecode
  • Improved type checking for Yul variables
  • Better error messages for invalid opcodes
function getChainId() external view returns (uint256 id) {

assembly {

id := chainid()

}

}

Breaking Changes

1. Stricter Type Conversion Rules

Implicit conversions between address and address payable are now more restricted.

// This no longer compiles

address payable recipient = msg.sender; // ERROR

// You must explicitly cast

address payable recipient = payable(msg.sender); // OK

2. Function Visibility in Interfaces

Functions in interfaces must now be explicitly marked external. The public visibility is no longer allowed.

// OLD (0.8.26) — worked but deprecated

interface IERC20 {

function transfer(address to, uint256 amount) public returns (bool);

}

// NEW (0.8.28) — required

interface IERC20 {

function transfer(address to, uint256 amount) external returns (bool);

}

3. Deprecated now Keyword Removed

The now keyword (alias for block.timestamp) is fully removed. Use block.timestamp instead.

// This no longer compiles

uint256 deadline = now + 1 days; // ERROR

// Use this instead

uint256 deadline = block.timestamp + 1 days; // OK

Migration Guide

Step 1: Update Compiler Version

In hardhat.config.ts or foundry.toml:

// Hardhat

solidity: {

version: "0.8.28",

settings: {

optimizer: { enabled: true, runs: 200 }

}

}

# Foundry

[profile.default]

solc_version = "0.8.28"

Step 2: Fix Breaking Changes

Run the compiler and fix errors one by one:

npx hardhat compile

# or

forge build

Common fixes:

  • Replace now with block.timestamp
  • Add payable(...) casts for address conversions
  • Change public to external in interfaces

Step 3: Adopt New Features

Look for optimization opportunities:

  • Replace storage-based reentrancy guards with transient storage
  • Use custom errors in require for better error handling
  • Refactor temporary state variables to transient

Step 4: Test Thoroughly

Run your full test suite:

npx hardhat test

# or

forge test -vvv

Pay special attention to:

  • Reentrancy guards behavior
  • Gas usage (transient storage should reduce costs)
  • Error message clarity in tests

Should You Upgrade?

Upgrade if:

  • You want 99% gas savings on reentrancy guards
  • You have temporary state variables (prime candidate for transient)
  • You're starting a new project

Wait if:

  • You're about to deploy to mainnet (test 0.8.28 on testnet first)
  • You have complex assembly code (test thoroughly)
  • Your codebase is very large (migration effort may not be worth it immediately)

Resources

Conclusion

Solidity 0.8.28 is a solid upgrade focused on developer experience and gas optimization. Transient storage alone makes it worth upgrading for most projects. The breaking changes are minimal and easy to fix.

Start experimenting with transient storage today — it's a powerful primitive that will shape how we write smart contracts going forward.

Prêt à mettre en pratique ?

Applique ces concepts avec des exercices interactifs sur Solingo.

Commencer gratuitement