Author: Vitalik Buterin

Translation: Karen, Foresight News

In Ethereum, resources have been limited until recently and are priced using a single resource called "Gas." Gas is a unit of measurement for the "computational effort" required to process specific transactions or blocks. Gas combines various types of "computational effort," with the most important ones being:

1. Raw computation (e.g., ADD, MULTIPLY);

2. Reading and writing to Ethereum storage (e.g., SSTORE, SLOAD, ETH transfers);

3. Data bandwidth;

4. Cost of generating ZK-SNARK proofs for blocks.

For example, the transaction I sent consumed a total of 47,085 Gas. This includes: (i) a base cost of 21,000 Gas, (ii) calldata bytes included as part of the transaction consuming 1556 Gas, (iii) storage read/write consuming 16,500 Gas, (iv) logging consuming 2149 Gas, with the rest used for EVM execution. The transaction fee that users must pay is directly proportional to the Gas consumed by the transaction. A block can contain a maximum of 30 million Gas, and the Gas price is continuously adjusted through the EIP-1559 targeting mechanism to ensure an average of 15 million Gas per block.

This approach has a major advantage: because all content is merged into a virtual resource, market design is very simple. Optimizing transactions to minimize costs is easy, optimizing blocks to collect as high fees as possible is relatively easy (excluding MEV), and there are no strange incentive mechanisms encouraging some transactions to be bundled with others to save costs.

However, this approach also has inefficiencies: it treats different resources as interchangeable when the actual underlying constraints are different. To understand this issue, you can first look at the following chart:

Gas limits impose a constraint:

The actual underlying security constraints are usually closer to:

This difference causes Gas limits to either unjustly exclude blocks that are actually secure, accept blocks that are actually insecure, or both.

If there are n resources with different security constraints, one-dimensional Gas may reduce throughput by up to n times. Therefore, people have long been interested in the concept of multi-dimensional Gas, and through EIP-4844, we have actually implemented multi-dimensional Gas on Ethereum. This article explores the advantages of this approach and the prospects for further enhancements.

Blob: Multi-dimensional Gas in Dencun

At the beginning of this year, the average block size was 150 kB. A large part of this is Rollup data: Layer2 protocols store data on-chain. This data is very expensive: although the cost of transactions on Rollup is only 5-10 times that of corresponding transactions on Ethereum L1, this cost is still too high for many use cases.

So why not reduce the Gas cost of calldata (currently 16 Gas for non-zero bytes, 4 Gas for zero bytes) to make Rollup cheaper? We have done this before, and we can do it again now. But the answer here is: the maximum block size is 30,000,000/16=1,875,000 non-zero bytes, and the network can barely or almost not handle blocks of this size. Lowering the cost by 4 times would increase the maximum to 7.5 MB, which would pose a huge risk to security.

This problem is ultimately solved by introducing a separate, Rollup-friendly data space (called blob) in each block.

These two resources have different prices and limits: after the Dencun hard fork, an Ethereum block can contain (i) 30 million Gas and (ii) 6 blobs, each capable of holding about 125 kB of calldata. These two resources have separate prices and are adjusted through a pricing mechanism similar to EIP-1559, with the goal of averaging 15 million Gas and 3 blobs per block.

As a result, the cost of Rollup has been reduced by 100 times, the transaction volume on Rollup has increased by more than 3 times, and the theoretical maximum block size has only slightly increased: from about 1.9 MB to about 2.6 MB.

Note: Rollup transaction fees provided by Growthepie.xyz. The Dencun fork occurred on March 13, 2024, introducing multi-dimensional pricing for blobs.

Multi-dimensional Gas and Stateless Clients

In the near future, storage proofs for stateless clients will also face similar issues. Stateless clients are a new type of client that will be able to verify the chain without needing to store a large amount or any data locally. Stateless clients achieve this by accepting proofs of specific parts of the Ethereum state that transactions in that block need to access.

The diagram shows a stateless client receiving a block and proof of the current values of the state-specific parts touched by the block's execution (e.g., account balances, code, storage), enabling nodes to verify a block without any storage.

A storage read costs 2100-2600 Gas, depending on the type of read, with storage write costs being higher. On average, a block will perform about 1000 storage read/write operations (including ETH balance checks, SSTORE and SLOAD calls, contract code reads, and other operations). However, the theoretical maximum is 30,000,000/2,100=14,285 reads. The bandwidth load of stateless clients is proportional to this number.

The current plan is to support stateless clients by transitioning Ethereum's State tree design from Merkle Patricia trees to Verkle trees. However, Verkle trees do not have post-quantum security and are not the optimal choice for newer STARK proof systems. Therefore, many are interested in supporting stateless clients through binary Merkle trees and STARKs, either completely skipping Verkle or upgrading to STARKs after a few years of Verkle transition, once STARKs become more mature.

STARK proofs based on binary hash tree branches have many advantages, but their key weakness is the long time it takes to generate proofs: Verkle trees can prove over 100,000 values per second, while hash-based STARKs typically prove only a few thousand hashes per second, and proving each value requires many hash "branches."

Considering today's predictions from highly optimized proof systems like Binius and Plonky3, as well as dedicated hashes like Vision-Mark-32, it seems that proving 1000 values per second is feasible for a while, but proving 14,285 values is not. An average block would be fine, but potential worst-case blocks (released by attackers) would disrupt the network.

Our default approach to handling such situations is repricing: increasing the cost of storage reads to reduce the maximum per block to a more secure level. However, we have done this many times already, and if done again, it would make too many applications too expensive. A better approach is multi-dimensional Gas: limiting and charging for storage access separately, keeping the average usage at 1000 storage accesses per block, but setting an upper limit per block, for example, 2000 accesses.

Universality of Multi-dimensional Gas

Another resource worth considering is the growth of state size: operations that increase the Ethereum state size, which subsequently require full nodes to store. The uniqueness of state size growth is that its limitation comes entirely from long-term sustained usage, not peak usage.

Therefore, adding a separate Gas dimension for operations that increase state size (e.g., zero-to-nonzero SSTORE, contract creation) may be valuable, but with a different goal: we can set a floating price targeting a specific average usage, without setting any limits per block.

This demonstrates a powerful property of multi-dimensional Gas: it allows us to separately inquire for each resource: (i) what is the ideal average usage? (ii) what is the secure maximum usage per block? Unlike setting Gas prices based on the maximum per block and letting the average usage follow, we have 2n degrees of freedom to set 2n parameters, adjusting each parameter based on considerations for network security.

In more complex scenarios, such as when security considerations for two resources partially overlap, this can be handled by making an opcode or resource consume a certain amount of Gas of multiple types (e.g., consuming multiple types of Gas for a zero-to-nonzero operation).