Ethereum 2.0 Serialization: Simple Serialize (SSZ)

Simple Serialize is the selected serialization algorithm for all data structures common across Ethereum 2.0 client implementations. It is specified in the official Ethereum 2.0 specification. The docs below outline how to use Simple Serialize and its external methods:



A type is Encodable if it implements EncodeSSZ and EncodeSSZSize function.

type Encodable interface {
EncodeSSZ(io.Writer) error
// Estimate the encoding size of the object without doing the actual encoding
EncodeSSZSize() (uint32, error)


A type is Decodable if it implements DecodeSSZ().

type Decodable interface {
DecodeSSZ(io.Reader) error


Encoding function

// Encode val and output the result into w.
func Encode(w io.Writer, val interface{}) error
// EncodeSize returns the target encoding size without doing the actual encoding.
// This is an optional pass. You don't need to call this before the encoding unless you
// want to know the output size first.
func EncodeSize(val interface{}) (uint32, error)

Decoding function

// Decode data read from r and output it into the object pointed by pointer val.
func Decode(r io.Reader, val interface{}) error


Say you have a struct like this

type exampleStruct1 struct {
Field1 uint8
Field2 []byte

You implement the Encoding interface for it:

func (e *exampleStruct1) EncodeSSZ(w io.Writer) error {
return Encode(w, *e)
func (e *exampleStruct1) EncodeSSZSize() (uint32, error) {
return EncodeSize(*e)

Now you can encode this object like this

e1 := &exampleStruct1{
Field1: 10,
Field2: []byte{1, 2, 3, 4},
wBuf := new(bytes.Buffer)
if err = e1.EncodeSSZ(wBuf); err != nil {
return fmt.Errorf("failed to encode: %v", err)
encoding := wBuf.Bytes() // encoding becomes [0 0 0 9 10 0 0 0 4 1 2 3 4]

You can also get the estimated encoding size

var encodeSize uint32
if encodeSize, err = e1.EncodeSSZSize(); err != nil {
return fmt.Errorf("failed to get encode size: %v", err)
// encodeSize becomes 13

Similarly, you can implement the Decodable interface for this struct

func (e *exampleStruct1) DecodeSSZ(r io.Reader) error {
return Decode(r, e)

Now you can decode to create new struct

e2 := new(exampleStruct1)
rBuf := bytes.NewReader(encoding)
if err = e2.DecodeSSZ(rBuf); err != nil {
return fmt.Errorf("failed to decode: %v", err)
// e2 now has the same content as e1


Supported data types

  • uint8

  • uint16

  • uint32

  • uint64

  • slice

  • array

  • struct

  • pointer