Ethereum Berlin hard fork is completed, what impact will it have on gas fees?

Ethereum Berlin hard fork is completed, what impact will it have on gas fees?

Quick Facts

  • The Berlin hard fork changes the gas cost of some opcodes. If the gas fee value is hardcoded in a dapp or a smart contract, they may stop running. If this happens, and the smart contract is not updatable, consumers will need to use EIP-2930's access list to use that part of the opcode.

  • Access lists can be used to reduce gas costs by a small amount, but they can actually increase total gas consumption in some cases.

  • geth adds a new RPC method called eth_createAccessList to simplify the creation of access lists.

Gas costs before the Berlin hard fork

Each opcode executed by the EVM has an associated gas cost. Most of these costs are fixed: PUSH1 always costs 3 units of gas, MUL costs 5, etc. Others vary: for example, the opcode cost of SHA3 depends on the size of its input.

We will mainly discuss the opcodes SLOAD and SSTORE, as they are the most affected by the Berlin hard fork. We will later discuss address-specific opcodes, such as all EXT* and CALL*, as their gas costs also changed.

Gas costs for SLOAD before Berlin

Before EIP-2929, the gas cost of SLOAD was simple: it always consumed 800 gas. So there is nothing to say (yet).

Gas cost of SSTORE before Berlin

SSTORE is probably the most complex opcode in terms of gas cost, as its cost depends on things like the current value of the storage slot, the new value, and whether it has been modified before. We will only analyze a few cases to get a basic understanding; if you want to learn more, read the EIP link at the end of the article.

  • If the value of the storage slot changes from 0 to 1 (or any non-zero value), the gas consumption is 20000.

  • If the value of the storage slot changes from 1 to 2 (or any other non-zero value), the gas consumption is 5000.

  • If the value of the storage slot changes from 1 (or any non-zero value) to 0, the gas cost is also 5000, but you will get 1 gas refund at the end of the transaction. This article will not discuss gas refunds as they are not affected by the Berlin hard fork.

  • If the value of the storage slot has been modified in the same transaction before, the gas consumption of all subsequent SSTOREs will be 800.

The details of this part are not interesting, the important thing is that SSTORE is expensive, and its cost depends on several factors.

Gas consumption after EIP-2929

EIP-2929 affects the gas consumption of all the above opcodes. But before we dive into these changes, we need to talk about an important concept introduced by this EIP: accessed addresses and accessed storage keys.

An address or a storage key is considered "accessed" if it has been "used" in a previous transaction. For example, when you CALL another contract, the address of that contract is marked as "accessed". Similarly, when you SLOAD or SSTORE some slots, the rest of the transaction is considered accessed. It doesn't matter which opcode executes it: if a SLOAD reads a slot, the following SLOAD and SSTORE will both be considered accessed.

It is worth noting here that storage keys are "built into" some addresses. As this EIP explains:

"While executing transactions, maintain a set of accessed_addresses: Set[Address] and accessed_storage_keys: Set[Tuple[Address, Bytes32]]"

That is, when we say a storage slot is accessed, we actually say a pair (address, storageKey) is accessed.

Next, let’s talk about the new gas consumption.

SLOAD after Berlin

Before the Berlin hard fork, SLOAD had a fixed cost of 800 gas. Now, it depends on whether the storage slot has been accessed. If it has not been accessed, the gas cost is 2100; if it has been accessed, it is 100. Therefore, if the slot is in the list of accessed storage keys, SLOAD's gas cost will be less than 2000.

SSTORE after Berlin

Let’s revisit the previous SSTORE example in the context of EIP-2929:

If the value of a storage slot changes from 0 to 1 (or any non-zero value), the gas cost is:

  • If the storage key has not been accessed, 22100

  • If it has been visited, 20000

If the value of the storage slot changes from 1 to 2 (or any other non-zero value), the gas consumption is:

  • If the storage key has not been accessed, 5000

  • If it has been visited, 2900

If the value of the storage slot changes from 1 (or any non-zero value) to 0, the gas cost is the same as the previous case, plus a refund.

If the value of the storage slot has been modified in the same transaction before, the gas consumption of all subsequent SSTOREs will be 100.

As you can see, if the slot that the SSTORE is modifying has been accessed before, the first SSTORE consumes less than 2100 gas.

Summarize

The following table compares the above values:

Note that in the last line there is no need to talk about whether the slot has been accessed, because if it has been written to before, then it has been accessed.

EIP-2930: Optional Access List Transactions

The other EIP we mentioned at the beginning was EIP-2930. This EIP adds a new transaction type that can include an access list in the transaction. This means that you can declare in advance which addresses and slots should be considered visited before the transaction execution begins. For example, a SLOAD to an unvisited slot costs 2100 gas, but if the slot is added to the transaction access list, the same opcode only costs 100 gas.

But if already accessed addresses or storage keys cost less gas, does that mean we can just add everything to the transaction access list to reduce gas costs? Great! No more gas fees! However, this is not entirely true, because you still need to pay gas fees every time you add an address or storage key.

Let's look at an example. Suppose we are sending a transaction to contract A, the access list may be as follows:

 accessList: [{
address: "",
storageKeys: [
    "0x000000000000000000000000000000000000000000000000000000000000000"
]
}]

If we send a transaction with this access list attached, the first opcode to use slot0x0 is SLOAD, which costs 100 gas instead of 2100. That's a reduction of 2000 gas. But each time we add a storage key to the access list of a transaction, it costs 1900 gas. So we only saved 100 gas. (If the first opcode to access the slot was SSTORE instead of SLOAD, we would save 2100 gas, which means we save 200 gas in total if we consider the cost of the storage key.)

Does this mean that we can save gas as long as we use transaction access lists? No, because we also need to pay for adding addresses to the access list (i.e. "

" ) of gas.

Visited addresses

So far, we have only discussed the opcodes SLOAD and SSTORE, but these are not the only opcodes that have changed with the Berlin upgrade. For example, the opcode CALL previously had a fixed cost of 700. But after EIP-2929, if the address is not in the access list, its cost has become 2600 gas, and if it is, it is 100 gas. Also, like accessed storage keys, no matter what opcode was accessed before (for example, if EXTCODESIZE is called for the first time, then this opcode will consume 2600 gas, and any subsequent EXTCODESIZE, CALL, or STATICCALL using the same address will only consume 100 gas).

How does this affect transactions with access lists? For example, if we send a transaction to contract A, and that contract calls another contract B, we can add a list like this:

 accessList: [{ address: "", storageKeys: [] }]

We will need to pay 2400 gas to add this access list to the transaction, but then the first opcode that uses B's address will only cost 100 gas, not 2600. So we saved 100 gas by doing this. If B uses its storage in some way, and we know which keys are used, we can also add them to the access list, saving 100-200 gas per key (depending on whether your first opcode is SLOAD or SSTORE).

But why are we talking about another contract? The contract we are calling? Why not perform these operations on this contract?

 accessList: [
  {address: "", storageKeys: []},
  {address: "", storageKeys: []},
]

We can do this, but it is not cost-effective because EIP-2929 clearly stipulates that the address of the contract being called (ie tx.to) will be added to the accessed_addresses list by default. Therefore, we do not need to pay the extra 2400 gas.

Let's analyze the previous example again:

 accessList: [{
address: "",
storageKeys: [
    "0x000000000000000000000000000000000000000000000000000000000000000"
]
}]

Unless we want to add more storage keys, this is actually wasteful. If we assume that SLOAD always uses the storage key first, then we need at least 24 storage keys to break even.

As you can imagine, doing analysis and manually creating an access list isn't that much fun. Fortunately, there is a better way.

eth_createAccessList RPC method

Geth (starting from version 1.10.2) has added a new eth_createAccessListRPC method that you can use to generate access lists. Its usage is similar to eth_estimateGas, but instead of returning a gas estimate, it returns a result like this:

 {
"accessList": [
{
      "address": "0xb0ee076d7779a6ce152283f009f4c32b5f88756c",
"storageKeys": [
        "0x000000000000000000000000000000000000000000000000000000000000000",
        "0x0000000000000000000000000000000000000000000000000000000000000001"
]
}
],
"gasUsed": "0x8496"
}

That is, it gives you the list of addresses and storage keys that the transaction will use, plus the gas cost if the access list was included. (Like eth_estimateGas, this is an estimate, and this list may change when the transaction is actually mined.) However, this does not mean that the gas cost will be lower than sending the same transaction without the access list!

I guess we'll figure out the right way to use it over time, but my guess is that the pseudo code would be something like this:

 let gasEstimation = estimateGas(tx)
let { accessList, gasUsed } = createAccessList(tx)
if (gasUsed > gasEstimation) {
delete accessList[tx.to]
}
tx.accessList = accessList;
sendTransaction(tx)

Loosen the contract

It is worth mentioning that the main purpose of access lists is not to use gas. As explained in the EIP:

“It mitigates the risk of contract breakage introduced by EIP-2929, because transactions can specify in advance the accounts and storage slots that the transaction plans to access and pay in advance; ultimately, in actual execution, the opcodes SLOAD and EXT* only consume 100 gas: this low gas consumption can not only prevent breakage caused by this EIP, but also "loosen" any contracts restricted by EIP-1884. ”

This means that if a contract makes assumptions about the cost of performing a transaction, an increase in gas costs may cause it to stop working. For example, a contract calling another contract like this someOtherContract.someFunction{gas: 34500}() will break because it assumes that someFunction will consume exactly 34500 gas. But if you add a reasonable access list, the contract will work again.

Do your own testing

If you want to test it yourself, clone the repository, which contains multiple examples that can be run with Hardhat and geth. See the README for instructions.

<<:  Chia official answer: 20 questions you need to know before participating in Chia mining

>>:  AMA Review | HECO Stars' Fantastic Fantasy Night Online Roundtable Forum

Recommend

What kind of woman is the most beautiful?

What kind of woman is the most beautiful? Everyon...

How to tell good or bad luck from the eyes

Eyes are the windows to the soul and one of the f...

Beard reveals a man's life achievements

Beard reveals a man's life achievements Beard...

Is it true that people with widow's peaks are more impatient?

As the saying goes, it is difficult to change one...

Do you dare to marry a man with facial features that are unlucky for your wife?

Whether it is a man or a woman, everyone hopes to...

4 key differences between Bitcoin Classic and Bitcoin Core

Bitcoin Core contributor彼得•托德was recently intervi...

BitShares founder: Lisk smart contracts are not smart, far inferior to Ethereum

Lisk smart contracts are not that smart. As a blo...

What does Tan Lang entering the spouse palace represent?

The star Tanlang is the celestial hub of the Big ...

Senior central bank official: How to regulate digital currency

This article is from China Finance magazine. The ...

Investment method based on the main star of the fate palace

People with different personalities have differen...