Documentation ¶
Overview ¶
Package rlp implements the RLP serialization format.
The purpose of RLP (Recursive Linear Prefix) qis to encode arbitrarily nested arrays of binary data, and RLP is the main encoding method used to serialize objects in Ethereum. The only purpose of RLP is to encode structure; encoding specific atomic data types (eg. strings, ints, floats) is left up to higher-order protocols; in Ethereum integers must be represented in big endian binary form with no leading zeroes (thus making the integer value zero be equivalent to the empty byte array).
RLP values are distinguished by a type tag. The type tag precedes the value in the input stream and defines the size and kind of the bytes that follow.
Index ¶
- Variables
- func Decode(r io.Reader, val interface{}) error
- func Encode(w io.Writer, val interface{}) error
- func EncodeToBytes(val interface{}) ([]byte, error)
- func EncodeToReader(val interface{}) (size int, r io.Reader, err error)
- type ByteReader
- type Decoder
- type Encoder
- type Kind
- type Stream
- func (s *Stream) Bytes() ([]byte, error)
- func (s *Stream) Decode(val interface{}) error
- func (s *Stream) Kind() (kind Kind, size uint64, err error)
- func (s *Stream) List() (size uint64, err error)
- func (s *Stream) ListEnd() error
- func (s *Stream) Reset(r io.Reader)
- func (s *Stream) Uint() (uint64, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // EOL is returned when the end of the current list // has been reached during streaming. EOL = errors.New("rlp: end of list") // Other errors ErrExpectedString = errors.New("rlp: expected String or Byte") ErrExpectedList = errors.New("rlp: expected List") ErrElemTooLarge = errors.New("rlp: element is larger than containing list") )
var ( // Common encoded values. // These are useful when implementing EncodeRLP. EmptyString = []byte{0x80} EmptyList = []byte{0xC0} )
Functions ¶
func Decode ¶
Decode parses RLP-encoded data from r and stores the result in the value pointed to by val. Val must be a non-nil pointer. If r does not implement ByteReader, Decode will do its own buffering.
Decode uses the following type-dependent decoding rules:
If the type implements the Decoder interface, decode calls DecodeRLP.
To decode into a pointer, Decode will set the pointer to nil if the input has size zero or the input is a single byte with value zero. If the input has nonzero size, Decode will allocate a new value of the type being pointed to.
To decode into a struct, Decode expects the input to be an RLP list. The decoded elements of the list are assigned to each public field in the order given by the struct's definition. If the input list has too few elements, no error is returned and the remaining fields will have the zero value. Recursive struct types are supported.
To decode into a slice, the input must be a list and the resulting slice will contain the input elements in order. As a special case, if the slice has a byte-size element type, the input can also be an RLP string.
To decode into a Go string, the input must be an RLP string. The bytes are taken as-is and will not necessarily be valid UTF-8.
To decode into an unsigned integer type, the input must also be an RLP string. The bytes are interpreted as a big endian representation of the integer. If the RLP string is larger than the bit size of the type, Decode will return an error. Decode also supports *big.Int. There is no size limit for big integers.
To decode into an interface value, Decode stores one of these in the value:
[]interface{}, for RLP lists []byte, for RLP strings
Non-empty interface types are not supported, nor are booleans, signed integers, floating point numbers, maps, channels and functions.
Example ¶
input, _ := hex.DecodeString("C90A1486666F6F626172") type example struct { A, B uint private uint // private fields are ignored String string } var s example err := Decode(bytes.NewReader(input), &s) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Decoded value: %#v\n", s) }
Output: Decoded value: rlp.example{A:0xa, B:0x14, private:0x0, String:"foobar"}
func Encode ¶ added in v0.8.4
Encode writes the RLP encoding of val to w. Note that Encode may perform many small writes in some cases. Consider making w buffered.
Encode uses the following type-dependent encoding rules:
If the type implements the Encoder interface, Encode calls EncodeRLP. This is true even for nil pointers, please see the documentation for Encoder.
To encode a pointer, the value being pointed to is encoded. For nil pointers, Encode will encode the zero value of the type. A nil pointer to a struct type always encodes as an empty RLP list.
Struct values are encoded as an RLP list of all their encoded public fields. Recursive struct types are supported.
To encode slices and arrays, the elements are encoded as an RLP list of the value's elements. Note that arrays and slices with element type uint8 or byte are always encoded as an RLP string.
A Go string is encoded as an RLP string.
An unsigned integer value is encoded as an RLP string. Zero always encodes as an empty RLP string. Encode also supports *big.Int.
An interface value encodes as the value contained in the interface.
Boolean values are not supported, nor are signed integers, floating point numbers, maps, channels and functions.
func EncodeToBytes ¶ added in v0.8.4
EncodeBytes returns the RLP encoding of val. Please see the documentation of Encode for the encoding rules.
func EncodeToReader ¶ added in v0.8.4
EncodeReader returns a reader from which the RLP encoding of val can be read. The returned size is the total size of the encoded data.
Please see the documentation of Encode for the encoding rules.
Types ¶
type ByteReader ¶
type ByteReader interface { io.Reader io.ByteReader }
ByteReader must be implemented by any input reader for a Stream. It is implemented by e.g. bufio.Reader and bytes.Reader.
type Decoder ¶
Decoder is implemented by types that require custom RLP decoding rules or need to decode into private fields.
The DecodeRLP method should read one value from the given Stream. It is not forbidden to read less or more, but it might be confusing.
type Encoder ¶ added in v0.8.4
type Encoder interface { // EncodeRLP should write the RLP encoding of its receiver to w. // If the implementation is a pointer method, it may also be // called for nil pointers. // // Implementations should generate valid RLP. The data written is // not verified at the moment, but a future version might. It is // recommended to write only a single value but writing multiple // values or no value at all is also permitted. EncodeRLP(io.Writer) error }
Encoder is implemented by types that require custom encoding rules or want to encode private fields.
Example ¶
package main import ( "fmt" "io" ) type MyCoolType struct { Name string a, b uint } // EncodeRLP writes x as RLP list [a, b] that omits the Name field. func (x *MyCoolType) EncodeRLP(w io.Writer) (err error) { // Note: the receiver can be a nil pointer. This allows you to // control the encoding of nil, but it also means that you have to // check for a nil receiver. if x == nil { err = Encode(w, []uint{0, 0}) } else { err = Encode(w, []uint{x.a, x.b}) } return err } func main() { var t *MyCoolType // t is nil pointer to MyCoolType bytes, _ := EncodeToBytes(t) fmt.Printf("%v → %X\n", t, bytes) t = &MyCoolType{Name: "foobar", a: 5, b: 6} bytes, _ = EncodeToBytes(t) fmt.Printf("%v → %X\n", t, bytes) }
Output: <nil> → C28080 &{foobar 5 6} → C20506
func Flat ¶ added in v0.8.4
func Flat(val interface{}) Encoder
Flat wraps a value (which must encode as a list) so it encodes as the list's elements.
Example: suppose you have defined a type
type foo struct { A, B uint }
Under normal encoding rules,
rlp.Encode(foo{1, 2}) --> 0xC20102
This function can help you achieve the following encoding:
rlp.Encode(rlp.Flat(foo{1, 2})) --> 0x0102
type Stream ¶
type Stream struct {
// contains filtered or unexported fields
}
Stream can be used for piecemeal decoding of an input stream. This is useful if the input is very large or if the decoding rules for a type depend on the input structure. Stream does not keep an internal buffer. After decoding a value, the input reader will be positioned just before the type information for the next value.
When decoding a list and the input position reaches the declared length of the list, all operations will return error EOL. The end of the list must be acknowledged using ListEnd to continue reading the enclosing list.
Stream is not safe for concurrent use.
Example ¶
input, _ := hex.DecodeString("C90A1486666F6F626172") s := NewStream(bytes.NewReader(input)) // Check what kind of value lies ahead kind, size, _ := s.Kind() fmt.Printf("Kind: %v size:%d\n", kind, size) // Enter the list if _, err := s.List(); err != nil { fmt.Printf("List error: %v\n", err) return } // Decode elements fmt.Println(s.Uint()) fmt.Println(s.Uint()) fmt.Println(s.Bytes()) // Acknowledge end of list if err := s.ListEnd(); err != nil { fmt.Printf("ListEnd error: %v\n", err) }
Output: Kind: List size:9 10 <nil> 20 <nil> [102 111 111 98 97 114] <nil>
func NewListStream ¶
NewListStream creates a new stream that pretends to be positioned at an encoded list of the given length.
func NewStream ¶
NewStream creates a new stream reading from r. If r does not implement ByteReader, the Stream will introduce its own buffering.
func (*Stream) Bytes ¶
Bytes reads an RLP string and returns its contents as a byte slice. If the input does not contain an RLP string, the returned error will be ErrExpectedString.
func (*Stream) Decode ¶
Decode decodes a value and stores the result in the value pointed to by val. Please see the documentation for the Decode function to learn about the decoding rules.
func (*Stream) Kind ¶
Kind returns the kind and size of the next value in the input stream.
The returned size is the number of bytes that make up the value. For kind == Byte, the size is zero because the value is contained in the type tag.
The first call to Kind will read size information from the input reader and leave it positioned at the start of the actual bytes of the value. Subsequent calls to Kind (until the value is decoded) will not advance the input reader and return cached information.
func (*Stream) List ¶
List starts decoding an RLP list. If the input does not contain a list, the returned error will be ErrExpectedList. When the list's end has been reached, any Stream operation will return EOL.
func (*Stream) ListEnd ¶
ListEnd returns to the enclosing list. The input reader must be positioned at the end of a list.