Ethereum Dencun: Rundown with examples

The Dencun upgrade activates on the mainnet at epoch 269568, so here's a quick rundown on all the EIPs included in the hardfork.

The EIPs here follow the same order as they are in the meta EIP-7569: Hardfork Meta - Dencun โ€” an EIP that lists all the EIPs of the hardfork & other hardfork details.

EIP-1153: Transient storage opcodes

Execution layer. EIP-1153 link.

This EIP adds a new type to storage: transient storage. With the EIP-1153 activation on the network, there are now three types of storage (previously two):

  • temporary memory storage โ€” byte-level storage that persists data during a function execution and is then discarded
  • transient storage โ€” data persists within one transaction (across all function executions) and is then discarded
  • permanent storage โ€” data persists across transactions & blocks

The transient storage opcodes are TSTORE and TLOAD.

Having no transient storage contributed to extra gas consumption quirks in Ethereum; the most well known one being users charged extra for interacting with the contracts implementing OpenZeppelin's Reentrancy Guard.

In practice, you will pay less on the execution level when interacting with the contracts that have functions that add no state change, like, again Reentrancy Guard.

Check out this nice deep dive into EIP-1153.

EIP-4788: Beacon block root in the EVM

Execution layer. EIP-4788 link.

EVM can now see the parent consensus layer (beacon chain) block root.

Practically, running an eth_getBlockByNumber | Ethereum after Dencun adds parentBeaconBlockRoot in the block details:

    "baseFeePerGas": "0x17357a9e30",
    "blobGasUsed": "0x0",
    "difficulty": "0x0",
    "excessBlobGas": "0x4c80000",
    "extraData": "0x34353131353565",
    "gasLimit": "0x1c9c380",
    "gasUsed": "0x9ee9e4",
    "hash": "0x632c2cf1d7d980760507f679d5bd3f07f1e767f63e28b193cbb2efbc86c95e53",
    "logsBloom": "0x42014...",
    "miner": "0x0c06b6d4ec451987e8c0b772ffcf7f080c46447a",
    "mixHash": "0xab9d05372e79c60cf348746f5772c9b28aad1164a1736611584b97080dca4999",
    "nonce": "0x0000000000000000",
    "number": "0x538e0e",
    "parentBeaconBlockRoot": "0x877cfcbcc3624e070c89287db70841834b9284dc135d674921e11a4c8fc68784", // <-- HERE
    "parentHash": "0x54ed6b5344a035b71cce3bd96ad84283fd2b56f63c76f8d3aab8e52974e7c6ba",
    "receiptsRoot": "0x3378df8d38bead81edb3f081f1f63a77a32f6e1f872c275ed8907aef59d0ba02",
    "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
    "size": "0xb7fd",
    "stateRoot": "0xfece204505a4cd70af610900fb5d116c291407c55d24d066177738edcf4c6431",
    "timestamp": "0x65f15304",
    "totalDifficulty": "0x3c656d23029ab0"

EIP-4844: Shard Blob Transactions

Consensus layer. Execution layer. EIP-4844 link.

This is your favorite one that's been covered multiple times by everyone, so here's a TLDR and a practical example.

TLDR

EIP-4844 makes rollup transactions cheaper because the EVM originally wasn't designed to execute the rollup batches and store them on the execution layer as part of a smart contract state. This is where the majority of your rollup transaction fees used to go to โ€” to execute & store the data on the execution layer as part of the contract state.

So EIP-4844 removes this "quirk" and implements as a sane version โ€” rollup batches can now be submitted as a special transaction type as pure data not executable by the EVM and the data is stored on the consensus layer for roughly 18 days. These are called data blobs or "sidecars" attached to blocks. This makes submitting & keeping the rollup data on Ethereum much cheaper and consequently the rollup transaction fees cheaper.

Let's now a have a practical walkthrough and get the data. (On Sepolia where the Dencun upgrade is already live).

Walkthrough with Arbitrum Sepolia

Check out the batches of transactions rolled up that Arbitrum is sending to Ethereum: Rollup batches.

Pick a batch. For example, batch 90169. See that the batch's L1 block number is 5475939.

Now let's do an eth_getBlockByNumber | Ethereum on block 5475939 to get the block's parentBeaconBlockRoot as discussed previously:

curl --request POST \
     --url https://ethereum-sepolia.core.chainstack.com/1fc2ff7e068591f6b44db1a454232d3d \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "eth_getBlockByNumber",
  "params": [
    "5475939",
    false
  ]
}
' | jq -r '.result.parentBeaconBlockRoot'

Use the value from the response in a Retrieve blob sidecar by root call to the consensus layer:

curl -X 'GET' \
  'https://ethereum-sepolia.core.chainstack.com/beacon/1fc2ff7e068591f6b44db1a454232d3d/eth/v1/beacon/blob_sidecars/0xbb7ef08755c4f394fd2e2cb325ac2228aa933d8a581e8e19e26f31f610ab118b' \
  -H 'accept: application/json'

The response is the rolled up batch 90169 of Arbitrum Sepolia transactions as attached to block 5475939 as a blob/side car.

Note that the blob lives for about 18 days, so make sure you use your own values.

EIP-5656: MCOPY - Memory copying instruction

Execution layer. EIP-5656 link.

Basically a new EVM operation that's also efficient & saves gas costs: where the EVM used to do MSTORE & MLOAD, the same thing can now be done with MCOPY. This depends on the smart contract developer implementation however.

EIP-6780: SELFDESTRUCT only in same transaction

Execution layer. EIP-6780 link.

SELFDESTRUCT, originally introduced as an understandable house cleaning opcode for developers โ€” to remove the no longer needed code from the Ethereum state, actually made metamorphic contracts possible through the use of CREATE2 & SELFDESTRUCT. You can deploy a contract, destroy the code, and then deploy a different contract to the same address. Example implementation.

Vitalik's thoughts on the issue.

This EIP makes the use of SELFDESTRUCT much more limited:

  • it can either be called with the full set of instructions (recovering funds to the target and deleting contract code) within the contract creation transaction
  • OR it's limited to only recovering the funds and NOT deleting the contract code

EIP-7044: Perpetually Valid Signed Voluntary Exits

Consensus layer. EIP-7044 link.

The EIP simplifies the process of exiting from staking positions for users doing non-custodial delegated staking.

Before EIP-7044, users in non-custodial delegated staking arrangements depended on the process required a voluntary exit message to be signed by the validator's signing key, which is typically controlled by the validator operator. Pre-signed voluntary exits were valid only for the current and previous consensus layer fork versions, creating a dependency on the validator operator to process exit requests in a timely manner.

After EIP-7044 activation, signed voluntary exit messages become perpetually valid, eliminating the need for them to be re-signed after future consensus layer upgrades. This change removes the uncertainty and reliance on validator operators for executing exit requests. Stakers now have more autonomy and assurance that they can exit their positions and access their funds at any time, without worrying about the validity of their pre-signed exit messages being affected by future network upgrades.

EIP-7045: Increase Max Attestation Inclusion Slot

Consensus layer. EIP-7045 link.

This EIP extends the timeframe within which validator attestations can be included in a block on the consensus layer. Previously, attestations had to be included within the window of 1 epoch (approximately 6.4 minutes, given that an epoch consists of 32 slots and each slot is 12 seconds). This was considered too narrow of a window.

EIP-7045 expands the window from 1 epoch to 2 epochs.

EIP-7514: Add Max Epoch Churn Limit

Consensus layer. EIP-7514 link.

EIP-7514 adds a max epoch churn limit to regulate the number of validators that can join or leave the network within a given epoch. It caps the churn limit at 8 validators per epoch to prevents the state-size bloat and the potential strain on network resources as the number of active validators increases. The churn limit, before this EIP, was variable with a minimum value of four and increased as more validators joined, but with EIP-7514, it's now fixed, preventing the active validator set from growing too rapidly.

EIP-7516: BLOBBASEFEE opcode

Execution layer. EIP-7516 link.

Tightly related to EIP-4844 (see above), this is a simple opcode BLOBBASEFEE allows contracts to manage data costs dynamically, especially for rollups. BLOBBASEFEE only costs 2 gas to execute and provides the value of the blob base-fee directly from the block header.

Track the eth_blobBaseFee implementation in Go Ethereum.

Ake

๐Ÿ› ๏ธ Developer Experience Director @ Chainstack
๐Ÿ’ธ Talk to me all things Web3 infrastructure and I'll save you the costs
Ake | Warpcast Ake | GitHub Ake | Twitter Ake | LinkedIN