description |
---|
This section contains information and functions related to Simple Serialize (SSZ) in Prysm. |
This documentation portal is depreciated and no longer maintained. Please visit docs.prylabs.network for the most recent iteration.
Simple Serialize (also known as SSZ) 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.
Simple Serialize contains support for bool
, uint8
, uint16
, uint32
, uint64
, slice
, array
, struct
and pointer
data types.
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
HashTreeRoot
SSZ marshals a value and packs its serialized bytes into leaves of a Merkle trie. It then determines the root of this trie.
HashTreeRoot
example:
func HashTreeRoot(val interface{}) ([32]byte, error)
- To begin, we create this basic struct:
type exampleStruct1 struct {
Field1 uint8
Field2 []byte
}
- 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)
}
- (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.
- (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.
- 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.
- 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)
}