---
# System prepended metadata

title: Simple Serialize (SSZ)

---

# Simple Serialize (SSZ)

This is a short recopilation about the technical concept about how simple serialize works on ethereum and what is it.

## What is it?

In short, SSZ is the serialization method used on the [Beacon chain](https://ethereum.org/en/roadmap/beacon-chain/).
SSZ is designed to be deterministic and to Merkleize efficiently

## How it works?

The goal of SSZ serialization is to represent objects of arbitrary complexity as strings of bytes.

SSZ serialization is not self-describing, so the schema must be known in advance.

Serialization involves converting each element of a composite type into little-endian byte strings. These byte strings are then joined together. For fixed-length elements, the serialized object has the bytelist representation in the same order as they appear in the deserialized object. For types with dynamic lengths, the data is replaced with an "offset." This offset is a kind of pointer that marks the start position of the dynamic value in the serialized object. The dynamic data is added to a heap at the end of the serialized object.

*The example below illustrates how the offsetting works for a container with both fixed and variable-length elements:*
```rust
struct Dummy {
        number1: u64,
        number2: u64,
        vector: Vec<u8>,
        number3: u64
    }
    dummy = Dummy{
        number1: 37,
        number2: 55,
        vector: vec![1,2,3,4],
        number3: 22,
    }
    serialized = ssz.serialize(dummy)

// Serialized would have the following structure (only padded to 4 bits here, padded 
// to 32 bits in reality, and keeping the int representation for clarity):

[37, 0, 0, 0, 55, 0, 0, 0, 16, 0, 0, 0, 22, 0, 0, 0, 1, 2, 3, 4]
------------  -----------  -----------  -----------  ----------
      |             |            |           |            |
   number1       number2    offset for    number 3    value for
                              vector                   vector

```

But remember, the data would actually be stored as bytelists:



```rust=
[
  10100101000000000000000000000000  # little-endian encoding of `number1`
  10110111000000000000000000000000  # little-endian encoding of `number2`.
  10010000000000000000000000000000  # The "offset" that indicates where the value of `vector` starts (little-endian 16).
  10010110000000000000000000000000  # little-endian encoding of `number3`.
  10000001100000101000001110000100   # The actual value of the `bytes` field.
]
```

## Deserialization

To deserialize the serialized object, the schema is required because it defines the layout of the serialized data. This schema is necessary as it tells the deserializer which values are actual values and which ones are offsets.

## Merkleization

The SSZ serialized objects can be merkleized.
Merkleization of an SSZ serialized object involves transforming it into a Merkle tree representation. The serialized object is divided into 32-byte chunks, which become the "leaves" of the tree. The total number of leaves must be a power of 2, so if necessary, additional leaves with 32 bytes of zeros are added to achieve this. The leaves are then hashed together to produce a single hash-tree root. In cases where leaves have varying depths, such as a container with multiple elements, the tree becomes uneven. Each element in the serialized list is assigned a generalized index, starting with the root as 1, and is calculated based on its position and the depth of the tree.

## Resources

https://ethereum.org/en/developers/docs/data-structures-and-encoding/ssz