---
eip: 6465
title: SSZ withdrawals root
description: Migration of withdrawals MPT commitment to SSZ
author: Etan Kissling (@etan-status), Mikhail Kalinin (@mkalinin)
discussions-to: https://ethereum-magicians.org/t/eip-6465-ssz-withdrawals-root/12883
status: Draft
type: Standards Track
category: Core
created: 2023-02-08
requires: 2718, 4895, 6404, 7495, 7916
---

## Abstract

This EIP defines a migration process of the existing Merkle Patricia Trie (MPT) commitment for withdrawals to [Simple Serialize (SSZ)](https://github.com/ethereum/consensus-specs/blob/b5c3b619887c7850a8c1d3540b471092be73ad84/ssz/simple-serialize.md).

## Motivation

While the consensus `ExecutionPayloadHeader` and the execution block header map to each other conceptually, they are encoded differently. This EIP aims to align the encoding of the `withdrawals_root`, taking advantage of the more modern SSZ format. This brings several advantages:

1. **Reducing complexity:** The proposed design reduces the number of use cases that require support for Merkle Patricia Trie (MPT).

2. **Reducing ambiguity:** The name `withdrawals_root` is currently used to refer to different roots. While the execution block header refers to a Merkle Patricia Trie (MPT) root, the consensus `ExecutionPayloadHeader` instead refers to an SSZ root. With these changes, `withdrawals_root` consistently refers to the same SSZ root.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

### Existing definitions

Definitions from existing specifications that are used throughout this document are replicated here for reference.

| Name | SSZ equivalent |
| - | - |
| [`ValidatorIndex`](https://github.com/ethereum/consensus-specs/blob/b5c3b619887c7850a8c1d3540b471092be73ad84/specs/phase0/beacon-chain.md#custom-types) | `uint64` |
| [`Gwei`](https://github.com/ethereum/consensus-specs/blob/b5c3b619887c7850a8c1d3540b471092be73ad84/specs/phase0/beacon-chain.md#custom-types) | `uint64` |
| [`ExecutionAddress`](https://github.com/ethereum/consensus-specs/blob/b5c3b619887c7850a8c1d3540b471092be73ad84/specs/bellatrix/beacon-chain.md#custom-types) | `Bytes20`
| [`WithdrawalIndex`](https://github.com/ethereum/consensus-specs/blob/b5c3b619887c7850a8c1d3540b471092be73ad84/specs/capella/beacon-chain.md#custom-types) | `uint64` |

### Withdrawals

New withdrawals use a normalized SSZ representation. The existing consensus [`Withdrawal`](https://github.com/ethereum/consensus-specs/blob/b5c3b619887c7850a8c1d3540b471092be73ad84/specs/capella/beacon-chain.md#withdrawal) SSZ container is migrated to [EIP-7495 `ProgressiveContainer`](./eip-7495.md).

```python
class Withdrawal(ProgressiveContainer(active_fields=[1, 1, 1, 1])):
    index: WithdrawalIndex
    validator_index: ValidatorIndex
    address: ExecutionAddress
    amount: Gwei
```

### Execution block header changes

The [execution block header's `withdrawals-root`](https://github.com/ethereum/devp2p/blob/bc76b9809a30e6dc5c8dcda996273f0f9bcf7108/caps/eth.md#block-encoding-and-validity) is transitioned from MPT to SSZ.

```python
withdrawals = ProgressiveList[Withdrawal](
    withdrawal_0, withdrawal_1, withdrawal_2, ...)

block_header.withdrawals_root = withdrawals.hash_tree_root()
```

### Consensus `ExecutionPayload` changes

When building a consensus `ExecutionPayload`, the [`withdrawals`](https://github.com/ethereum/consensus-specs/blob/b5c3b619887c7850a8c1d3540b471092be73ad84/specs/deneb/beacon-chain.md#executionpayload) list is based on the new progressive container type.

```python
class ExecutionPayload(...):
    ...
    withdrawals: ProgressiveList[Withdrawal]
    ...
```

The state transition function is updated to limit withdrawals to [`MAX_WITHDRAWALS_PER_PAYLOAD`](https://github.com/ethereum/consensus-specs/blob/b5c3b619887c7850a8c1d3540b471092be73ad84/specs/capella/beacon-chain.md#execution).

## Rationale

This change was originally a candidate for inclusion in Shanghai, but was postponed to accelerate the rollout of withdrawals.

## Backwards Compatibility

Applications that rely on the replaced MPT `withdrawals_root` in the block header require migration to the SSZ `withdrawals_root`.

RLP and SSZ withdrawals may clash when encoded. It is essential to use only a single format within one channel. The block header corresponding to the withdrawals can be consulted to identify the underlying fork.

## Security Considerations

None

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
