Skip to content

Instantly share code, notes, and snippets.

@Thegaram
Last active May 8, 2025 21:16
Show Gist options
  • Select an option

  • Save Thegaram/64b5d43144d5740f01907b48d986b8e7 to your computer and use it in GitHub Desktop.

Select an option

Save Thegaram/64b5d43144d5740f01907b48d986b8e7 to your computer and use it in GitHub Desktop.
author date
Péter Garamvölgyi
2025-01-10

Deep Dive into Pectra EIPs

2025-01-10

@ Scroll Knowledge Sharing


Pectra EIPs (as per EIP-7600)

EVM

Blobs & Calldata

CL & Staking


General Resources

For a quick summary, read these:

Tim Beiko's post.

OAK Research's summary


Considerations

Context and Motivation

Dev/User Perspective

Protocol Perspective

Impact on Rollups


EIP-7702: Set EOA account code

Add a new tx type that sets the code for an EOA


EIP-7702: Set EOA account code -- Context and Motivation

AA (Account Abstraction) has been progressing slowly

ERC-4337 is in production, but most accounts are still EOAs

--

EIP-7702 allows users to upgrade their EOAs into smart contracts

Mix of EOA and smart contract:

  • EOA: Can sign tx with private key (set account as tx.from)
  • Smart contract: Can send tx to account and trigger code execution (set account as tx.to)

Use cases: Batching, sponsorship, multisigs, session keys, etc.


EIP-7702: Set EOA account code -- Dev/User Perspective (1)

Example: Deposit USDT to Scroll without EIP-7702.

Tx #1: Approve.

> cast send "$usdt" \
    "approve(address,uint256)" "$erc20_gateway" "$amount" \
    --from "$alice" --unlocked

Tx #2: Deposit.

> cast send "$erc20_gateway" \
    "depositERC20(address,uint256,uint256)" "$usdt" "$amount" "$gas" \
    --value $fee \
    --from "$alice" --unlocked

Note: These txs are sent from Alice's account.


EIP-7702: Set EOA account code -- Dev/User Perspective (2)

Example: Deposit USDT to Scroll with EIP-7702.

Set EOA code to MultiCall:

# At first, account is an EOA with no code
> cast code "$alice"
0x

# Set delegated code
> cast send --from "$alice" --private-key "$alice_pk" --auth "$multicall" $(cast az)

# Account now has a special code delegation, stored persistently in state
> cast code "$alice"
0xef0100ca11bde05977b3631167028862be2a173976ca11

Note:

  • 0xef0100 is a special prefix
  • 0xca11bde05977b3631167028862be2a173976ca11 is the MultiCall contract address.

EIP-7702: Set EOA account code -- Dev/User Perspective (3)

A single tx: Send batch.

> calls=()

> calldata=$(cast calldata "approve(address,uint256)" "$erc20_gateway" "$amount")
> calls+=("($usdt, false, 0, $calldata)")

> calldata=$(cast calldata "depositERC20(address,uint256,uint256)" "$usdt" "$amount" "$gas")
> calls+=("($erc20_gateway, false, $fee, $calldata)")

# ...

> cast send "$alice" "aggregate3Value((address,bool,uint256,bytes)[] calldata calls)" \
    "[${calls[1]}, ${calls[2]}}]" \
     --value $fee \
    --from "$alice" --unlocked

Note: This tx is sent to Alice's account.


EIP-7702: Set EOA account code -- Dev/User Perspective (4)

This is already testable with ithaca.xyz's Odyssey devnet, integrated into Anvil:

> anvil --fork-url "$eth_rpc" --auto-impersonate --odyssey

Full example: https://gist.github.com/Thegaram/51a49a829b2a13ebc88990894a30912b


EIP-7702: Set EOA account code -- Protocol Perspective (1)

EIP-7702 defines a new transaction type:

type SetCodeTx struct {
    ChainID    uint64
    Nonce      uint64
    GasTipCap  *uint256.Int
    GasFeeCap  *uint256.Int
    Gas        uint64
    To         common.Address
    Value      *uint256.Int
    Data       []byte
    AccessList AccessList
    AuthList   []SetCodeAuthorization // <-- this is new

    V *uint256.Int `json:"v" gencodec:"required"`
    R *uint256.Int `json:"r" gencodec:"required"`
    S *uint256.Int `json:"s" gencodec:"required"`
}

https://github.com/ethereum/go-ethereum/blob/master/core/types/tx_setcode.go


EIP-7702: Set EOA account code -- Protocol Perspective (2)

Authorizations are applied before the EVM call:

// Increment the nonce for the next transaction.
st.state.SetNonce(msg.From, st.state.GetNonce(msg.From)+1)

// Apply EIP-7702 authorizations.
for _, auth := range msg.AuthList {
    st.applyAuthorization(msg, &auth)
}

// ...

// Execute the transaction's call.
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value)

EIP-7702: Set EOA account code -- Protocol Perspective (3)

Applying the authorization means bumping account nonce and setting code:

authority, err := st.validateAuthorization(auth)

// ...

// Update nonce and account code.
st.state.SetNonce(authority, auth.Nonce+1)

// Install delegation to auth.Address.
st.state.SetCode(authority, types.AddressToDelegation(auth.Address))

EIP-7702: Set EOA account code -- Impact on Rollups

Rollups like Scroll should adopt EIP-7702.

We can also build custom user experiences using EIP-7702.


EIP-7702: Set EOA account code -- Resources

Original EIP https://eips.ethereum.org/EIPS/eip-7702

Colin's writeup https://hackmd.io/@colinlyguo/SyAZWMmr1x

Ithaca experiment with passkeys https://www.ithaca.xyz/writings/exp-0001

Viem docs https://viem.sh/experimental/eip7702


EIP-2537: Precompile for BLS12-381 curve operations

Adds operation on BLS12-381 curve as a precompile in a set necessary to efficiently perform operations such as BLS signature verification.


EIP-2537: Precompile for BLS12-381 curve operations -- Context and Motivation (1)

Proposed in 2020.

Existing precompiles operate on the BN254 (aka alt_bn128) curve.

0x06 ecAdd, 0x07 ecMul, 0x08 ecPairing

EIP-2537 adds 7 new precompiles for BLS12-381 curve operations.

BLS12-381 is pairing-friendly elliptic curve.


EIP-2537: Precompile for BLS12-381 curve operations -- Context and Motivation (2)

BLS12-381 is used in Ethereum's consensus layer.

For signing transactions, Ethereum uses ECDSA signatures with the secp256k1 elliptic curve.

However, the beacon chain protocol uses BLS signatures with the BLS12-381 elliptic curve.

the pairing property of BLS signatures allows us to aggregate signatures, thus making the whole consensus protocol practical.

https://eth2book.info/capella/part2/building_blocks/signatures

--

Note!

BLS digital signature: Boneh–Lynn–Shacham

BLS12–381: Barreto-Lynn-Scott


EIP-2537: Precompile for BLS12-381 curve operations -- Dev/User Perspective

BLS12–381 has better security (120 bits).

BLS12–381 can support signature aggregation (BLS digital signature).

With EIP-2537, we can verify Ethereum's consensus inside the EVM, unlocking use cases:

  • Registration of distributed validators
  • Light client constructions
  • Randomness beacons

EIP-2537 could also unlock more efficient zkSNARKs (better security, larger circuit size) and other advanced cryptographic constructions (e.g. timelock decryption).


EIP-2537: Precompile for BLS12-381 curve operations -- Protocol Perspective

EIP-2537 adds 7 new precompiles.

(Geth still has 9, 2 were recently removed from the EIP as redundant.)

// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
// contracts specified in EIP-2537. These are exported for testing purposes.
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
    common.BytesToAddress([]byte{10}): &bls12381G1Add{},
    common.BytesToAddress([]byte{11}): &bls12381G1Mul{},
    common.BytesToAddress([]byte{12}): &bls12381G1MultiExp{},
    common.BytesToAddress([]byte{13}): &bls12381G2Add{},
    common.BytesToAddress([]byte{14}): &bls12381G2Mul{},
    common.BytesToAddress([]byte{15}): &bls12381G2MultiExp{},
    common.BytesToAddress([]byte{16}): &bls12381Pairing{},
    common.BytesToAddress([]byte{17}): &bls12381MapG1{},
    common.BytesToAddress([]byte{18}): &bls12381MapG2{},
}

EIP-2537: Precompile for BLS12-381 curve operations -- Impact on Rollups

Rollups should consider supporting EIP-2537 for compatibility.

Rollups might also benefit from more efficient verifier contracts using EIP-2537.


EIP-2537: Precompile for BLS12-381 curve operations -- Resources

Original EIP https://eips.ethereum.org/EIPS/eip-2537

BLS12-381 For The Rest Of Us https://hackmd.io/@benjaminion/bls12-381

BN254 For The Rest Of Us https://hackmd.io/@jpw/bn254

PEEPanEIP#133: EIP-2537 https://www.youtube.com/watch?v=Kr0WRewb_AA

https://x.com/LogarithmicRex/status/1864688474030526784


EIP-2935: Save historical block hashes in state

Store and serve last 8192 block hashes as storage slots of a system contract to allow for stateless execution


EIP-2935: Save historical block hashes in state -- Context and Motivation

Proposed in 2020.

The EVM's blockhash opcode can access the most recent 256 block hashes.

Stateless clients (Verkle or otherwise) might not have these.

Instead, we include block hashes in state, then we can provide these are part of the witness.


EIP-2935: Save historical block hashes in state -- Dev/User Perspective

EIP-2935 is necessary for stateless clients.

--

This EIP might also be used by dapps that need to perform historical header verification.

These dapps can simply read block hashes from contract storage.

Example code (not tested, probably not 100% correct):

HISTORY_STORAGE_ADDRESS="0x0F792be4B0c0cb4DAE440Ef133E90C0eCD48CCCC"
HISTORY_SERVE_WINDOW=8191

block_number=$(($(cast block-number) - 1000))

cast call "$HISTORY_STORAGE_ADDRESS" $(cast --to-hex $block_number)

cast storage "$HISTORY_STORAGE_ADDRESS" $(($block_number % $HISTORY_SERVE_WINDOW))

EIP-2935: Save historical block hashes in state -- Protocol Perspective (1)

System contract:

This concept was originally introduced in EIP-4788.

Now similar mechanisms are used in EIP-4788, EIP-2935, EIP-6110, EIP-7002, ...

--

EIP-2935 system contract:

EVM code that stores block hash in a ring buffer when executed from a special system caller.

For other callers, it simply serves block hashes from contract storage.


EIP-2935: Save historical block hashes in state -- Protocol Perspective (2)

Special state-update operation during block processing (before tx execution):

// If prague hardfork, insert parent block hash in the state as per EIP-2935.
if eth.blockchain.Config().IsPrague(block.Number(), block.Time()) {
    core.ProcessParentBlockHash(block.ParentHash(), evm)
}

State will change, even if the block is empty!


EIP-2935: Save historical block hashes in state -- Protocol Perspective (3)

func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) {
    // ...
    msg := &Message{
        From:      params.SystemAddress,
        GasLimit:  30_000_000,
        GasPrice:  common.Big0,
        GasFeeCap: common.Big0,
        GasTipCap: common.Big0,
        To:        &params.HistoryStorageAddress,
        Data:      prevHash.Bytes(),
    }
    // ...
    _, _, _ = evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560)
    evm.StateDB.Finalise(true)
}

Note: The behavior of the blockhash opcode does not change.


EIP-2935: Save historical block hashes in state -- Impact on Rollups

Trustless block hash relay:

ScrollChain needs access to some past L1 block hash to provide it as public input.

This becomes much easier if we have access to >256 block hashes.


EIP-2935: Save historical block hashes in state -- Resources

Original EIP https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2935.md

Peep an EIP #10: EIP-2935 (outdated) https://www.youtube.com/watch?v=QH5yuNd3B6o

Revm PR (outdated) bluealloy/revm#1354


EIP-7691: Blob throughput increase

Increase the number of blobs to reach a new target and max of 6 and 9 blobs per block respectively


EIP-7691: Blob throughput increase -- Context and Motivation

Rollups need more blob throughput!

https://blobscan.com/stats

Change target/max from 3/6 to 6/9

The values 3/6 were chosen cautiously, but the network looks stable now

EIP-7691 is a quick throughput increase before PeerDAS


EIP-7691: Blob throughput increase -- Protocol Perspective

Before: 1:2 ratio

Full blobs: basefee increases by ~12.5%

No Blobs: basefee decreases by ~11.1%

--

Now: 2:3 ratio

Full blobs: basefee increases by ~8.2%

No Blobs: basefee decreases by ~14.5%

--

Blob base fee becomes more responsive to empty blobs.


EIP-7691: Blob throughput increase -- Impact on Rollups

Lower fees, unlock more L2 throughput.


EIP-7691: Blob throughput increase -- Resources

Original EIP https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7691.md

Prysm PR OffchainLabs/prysm#14750


EIP-7840: Add blob schedule to EL config files

Include a per-fork schedule of max and target blob counts in client configuration files


EIP-7840: Add blob schedule to EL config files -- Context and Motivation

Define the format of how EL clients should follow blob config changes.

This became relevant after EIP-7691: Blob throughput increase.

New entries in genesis.json:

"blobSchedule": {
  "cancun": { "target": 3, "max": 6 },
  "prague": { "target": 6, "max": 9 },
  ...
}

EIP-7840: Add blob schedule to EL config files -- Resources

Original EIP https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7840.md


EIP-7623: Increase calldata cost

Increase calldata cost to reduce maximum block size


EIP-7623: Increase calldata cost -- Context and Motivation

Current block size: Theoretical max is 7.15 MB, while average is 100 KB or less.

--

This EIP aims to reduce max size.

Make max p2p payload size more predictable.

Make room for raising gas limit and/or blob count.


EIP-7623: Increase calldata cost -- Protocol Perspective

Differentiate between computation-heavy and data-heavy txs in gas formula.

Increase calldata costs from 4/16 to 10/40 gas per byte for data-heavy transactions.

Limit the size of data-heavy transactions that can fit into a single block.


EIP-7623: Increase calldata cost -- Impact on Rollups

No major impact since we use blobs, not calldata for DA.

However, our gas estimation will need to be adjusted.

--

Rollups should consider adopting this EIP so that their gas pricing is consistent with Ethereum.

To avoid "double charging" users, L1 data fee coefficients should be decreased accordingly.


EIP-7623: Increase calldata cost -- Resources

Original EIP https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7623.md

Short overview https://x.com/eawosikaa/status/1821650549944525084

Research analysis https://ethresear.ch/t/analyzing-eip-7623-increase-calldata-cost/19002


EIP-7685: General purpose execution layer requests

A general purpose bus for sharing EL triggered requests with the CL


EIP-7685: General purpose execution layer requests -- Context and Motivation

The Engine API was not suitable for relaying contract-triggered requests from EL to CL.

This EIP solves this, and this is used by other Pectra EIPs:

EIP-6110: Supply validator deposits on chain

EIP-7002: Execution layer triggerable exits

EIP-7251: Increase the MAX_EFFECTIVE_BALANCE


EIP-7685: General purpose execution layer requests -- Protocol Perspective (1)

Define abstract request type:

requests = request_type ++ request_data

These are returned to CL in the Engine API response:

  • Add requests to the payload.

  • Add requests_hash to block header.

Generic: Different applications of EIP-7685 can define their own encoding, CL logic, etc.


EIP-7685: General purpose execution layer requests -- Protocol Perspective (2)

// Build block
err := miner.fillTransactions(interrupt, work)
// ...

// Collect consensus-layer requests if Prague is enabled.
var requests [][]byte

// EIP-6110 deposits
if err := core.ParseDepositLogs(&requests, allLogs, miner.chainConfig); err != nil {
    return &newPayloadResult{err: err}
}

// EIP-7002
core.ProcessWithdrawalQueue(&requests, work.evm)

// EIP-7251 consolidations
core.ProcessConsolidationQueue(&requests, work.evm)

work.header.RequestsHash = &types.CalcRequestsHash(requests)

https://github.com/ethereum/go-ethereum/blob/master/miner/worker.go


EIP-7685: General purpose execution layer requests -- Impact on Rollups

Block header format change, might need to adjust the SDKs we use to interact with L1.


EIP-7685: General purpose execution layer requests -- Resources

Original EIP https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7685.md

PEEPanEIP#132: EIP-7685 https://www.youtube.com/watch?v=3g71BGZFASE

Summary by EIP Fun https://x.com/EIPFun/status/1864270492376682684


EIP-6110: Supply validator deposits on chain

Provides validator deposits as a list of deposit operations added to the Execution Layer block


EIP-6110: Supply validator deposits on chain -- Context and Motivation

Currently Ethereum relies on proposer voting to process validator deposits.

Basically CL must keep polling EL (eth_getLogs) with a certain delay, then reach consensus on the results (deposit logs).

This change simplifies this by switching to in-protocol deposit processing.


EIP-6110: Supply validator deposits on chain -- Dev/User Perspective

Better security, validators will not accept fake deposits even when more than 2/3 portion of stake is adversarial.

Better validator UX, decrease deposit delay from ~12 hours to ~13 minutes.


EIP-6110: Supply validator deposits on chain -- Protocol Perspective

Builds on EIP-7685: General purpose execution layer requests.

request_type = 0x00
request_data = get_deposit_request_data(block.receipts)

EL simply collects deposit logs and returns them to CL:

def get_deposit_request_data(receipts)
    # Retrieve all deposits made in the block
    deposit_requests = []
    for receipt in receipts:
        for log in receipt.logs:
            if log.address == DEPOSIT_CONTRACT_ADDRESS:
                deposit_request = event_data_to_deposit_request(log.data)
                deposit_requests.append(deposit_request)

EIP-6110: Supply validator deposits on chain -- Resources

Original EIP https://github.com/ethereum/EIPs/blob/master/EIPS/eip-6110.md

EIPs For Nerds #4: EIP-6110 https://ethereum2077.substack.com/p/eip-6110-supply-validator-deposits-onchain

Understanding EIP-7002 and EIP-6110 | Devcon SEA https://www.youtube.com/watch?v=EyDChjFQEkQ

https://eips.wiki/eips/protocol/consensus/eip-6110/


EIP-7002: Execution layer triggerable exits

Allow validators to trigger exits and partial withdrawals via their execution layer (0x01) withdrawal credentials


EIP-7002: Execution layer triggerable exits -- Context and Motivation

Validators have two keys:

Validator key (BLS key)

Withdrawal key (BLS key or normal Ethereum account, can be a contract)

--

Currently validators can only initiate exit using their validator key.

But withdrawn funds go to the withdrawal key.

This EIP will allow users to withdraw with both identities.


EIP-7002: Execution layer triggerable exits -- Dev/User Perspective

Can recover funds even if validator key is lost. We can also implement social recovery.

Can allow more sophisticated staking, e.g. where the two roles are operated by different entities.

Withdrawal contracts can implement complex rules, allowing for much safer automation.


EIP-7002: Execution layer triggerable exits -- Protocol Perspective

Builds on EIP-7685: General purpose execution layer requests.

request_type = 0x01
request_data = read_withdrawal_requests()

Requests are submitted to and read from the WITHDRAWAL_REQUEST_PREDEPLOY contract.


EIP-7002: Execution layer triggerable exits -- Impact on Rollups

Might be relevant for "native yield" staking.


EIP-7002: Execution layer triggerable exits -- Resources

Original EIP https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7002.md

Twitter thread https://x.com/Figment_io/status/1859317234000330883

PEEPanEIP#128: EIP-7002 https://www.youtube.com/watch?v=MxvX1gNh-_4

Understanding EIP-7002 and EIP-6110 | Devcon SEA https://www.youtube.com/watch?v=EyDChjFQEkQ


EIP-7251: Increase the MAX_EFFECTIVE_BALANCE

Allow validators to have larger effective balances, while maintaining the 32 ETH lower bound.


EIP-7251: Increase the MAX_EFFECTIVE_BALANCE -- Context and Motivation

Currently validator stake must be exactly 32 ETH.

If you have more, you need to run multiple validators.

It is hard to re-stake rewards, need to wait until you have earned 32 ETH or more.

Having many validators leads to more overhead for nodes, limiting Ethereum CL's scalability.


EIP-7251: Increase the MAX_EFFECTIVE_BALANCE -- Dev/User Perspective

After EIP-7251:

Large node operators can consolidate into fewer validators.

Solo-stakers can earn compounding rewards and stake in more flexible increments.


EIP-7251: Increase the MAX_EFFECTIVE_BALANCE -- Protocol Perspective

Builds on EIP-7685: General purpose execution layer requests.

request_type = 0x02
request_data = dequeue_consolidation_requests()

Requests are submitted to and read from the CONSOLIDATION_REQUEST_PREDEPLOY contract.

--

Reduce validator set without reducing security

Reduce the number of P2P messages over the network

Reduce the number of BLS signatures that need to be aggregated


EIP-7251: Increase the MAX_EFFECTIVE_BALANCE -- Impact on Rollups

Might be relevant for "native yield" staking.


EIP-7251: Increase the MAX_EFFECTIVE_BALANCE -- Resources

Original EIP https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7251.md

Unchained overview https://unchainedcrypto.com/eip-7251-maxeb-ethereum/

EIP 7251 Explainer https://medium.com/@james_gaps/eip-7251-explainer-aa10558b9150

EIPs For Nerds #3: EIP-7251 https://ethereum2077.substack.com/p/eip-7251-increase-max-effective-balance

EIP-7251 - Maximum effective balance overview by Paul Harris | Devcon SEA https://www.youtube.com/watch?v=EwW6dNi9VCY

EIP-7251 for Staking Pool Operators https://hackmd.io/@wmoBhF17RAOH2NZ5bNXJVg/S1U86pzgR

In-Depth Analysis of Ethereum EIP-7251 https://zhangyuting.medium.com/in-depth-analysis-of-ethereum-eip-7251-the-future-of-validator-consolidation-and-opportunities-947ec32df544


EIP-7549: Move committee index outside Attestation

Move committee index outside of the signed Attestation message


EIP-7549: Move committee index outside Attestation -- Context and Motivation

Attestation message consists of 3 elements:

LMD GHOST vote (beacon_block_root, slot)

FFG vote (source, target)

Committee index (index)

--

EIP-7549 proposes to (re)move the 3rd item, so that identical votes can be aggregated.

This results in better aggregation, reduced verification load (62x) and the ability to store more on-chain attestations in each block.


EIP-7549: Move committee index outside Attestation -- Dev/User Perspective

Make Casper FFG verification more efficient, especially for zk clients (beam chain).


EIP-7549: Move committee index outside Attestation -- Resources

Original EIP https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7549.md

EIP-7549: optimal on chain aggregation https://hackmd.io/@n0ble/eip7549_onchain_aggregates

PEEPanEIP#131: EIP-7549 https://www.youtube.com/watch?v=oZfV4Ell9WQ


Deep Dive into Pectra EIPs

2025-01-10

@ Scroll Knowledge Sharing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment