Skip to content

fuzzitdev/go-ssz

 
 

Repository files navigation

Build Status codecov Documentation Discord Gitter

Simple Serialize (SSZ)

Simple Serialize is the serialization algorithm standard for all data structures common across Ethereum 2.0 client implementations. It is outlined in the official Ethereum 2.0 specification.

Need assistance?

A more in-depth breakdown of SSZ is available in this section of our official documentation. If you still have questions, feel free to stop by either our Discord or Gitter and a member of the team or our community will be happy to assist you.

Functionality

Marshal & Unmarshal

Our simple serialize API is designed to match the syntax of the popular JSON marshal / unmarshal API from the Go standard library. Below are samples of each in use:

marshal example:

// Marshal val and output the result.
func Marshal(val interface{}) ([]byte, error)

unmarshal example:

// Unmarshal data from input and output it into the object pointed by pointer val.
func Unmarshal(input []byte, val interface{}) error

Tree hashing

HashTreeRoot SSZ marshals a value and packs its serialized bytes into leaves of a Merkle trie. It then determines the root of this trie.

HashTreeRootexample:

func HashTreeRoot(val interface{}) ([32]byte, error)

Usage examples

Notice: SSZ supports bool, uint8, uint16, uint32, uint64, slice, array, struct and pointer data types.

Encoding an object (Marshal)

  1. To begin, we create this basic struct:
type exampleStruct1 struct {
    Field1 uint8
    Field2 []byte
}
  1. Next, we can encode the defined object like so:
e1 := exampleStruct1{
    Field1: 10,
    Field2: []byte{1, 2, 3, 4},
}
encoded, err := Marshal(e1)
if err != nil {
    return fmt.Errorf("failed to marshal: %v", err)
}
  1. (Optional) It is also possible to specify the size of a struct's field by utilising ssz-specific field tags:
type exampleStruct struct {
    Field1 uint8
    Field2 []byte `ssz:"size=32"`
}

This will treat Field2 as as [32]byte array when marshaling.

  1. (Optional) For unbounded fields or multidimensional slices, SSZ size tags can also be used:
type exampleStruct struct {
    Field1 uint8
    Field2 [][]byte `ssz:"size=?,32"`
}

This will treat Field2 as type [][32]byte when marshaling a struct of that type.

Decoding an object (Unmarshal)

  1. Similarly, you can unmarshal encoded bytes into its original form:
var e2 exampleStruct
if err = Unmarshal(encoded, &e2); err != nil {
    return fmt.Errorf("failed to unmarshal: %v", err)
}
reflect.DeepEqual(e1, e2) // Returns true as e2 now has the same content as e1.

Calculating the tree-hash (HashTreeRoot)

  1. To calculate tree-hash root of the object run:
root, err := HashTreeRoot(e1)
if err != nil {
    return fmt.Errorf("failed to compute Merkle root: %v", err)
}

Contributing

We have put all of our contribution guidelines into CONTRIBUTING.md! Check it out to get started.

License

Brought to you by Prysmatic Labs with a permissive Apache License 2.0.

Releases

No releases published

Packages

No packages published

Languages

  • Go 89.8%
  • Python 10.2%