1 # Wire encoding for Golang
3 This software implements Go bindings for the Wire encoding protocol.
4 The goal of the Wire encoding protocol is to be a simple language-agnostic encoding protocol for rapid prototyping of blockchain applications.
6 This package also includes a compatible (and slower) JSON codec.
10 **Primary types**: `uvarint`, `varint`, `byte`, `uint[8,16,32,64]`, `int[8,16,32,64]`, `string`, and `time` types are supported
12 **Arrays**: Arrays can hold items of any arbitrary type. For example, byte-arrays and byte-array-arrays are supported.
14 **Structs**: Struct fields are encoded by value (without the key name) in the order that they are declared in the struct. In this way it is similar to Apache Avro.
16 **Interfaces**: Interfaces are like union types where the value can be any non-interface type. The actual value is preceded by a single "type byte" that shows which concrete is encoded.
18 **Pointers**: Pointers are like optional fields. The first byte is 0x00 to denote a null pointer (e.g. no value), otherwise it is 0x01.
22 **Maps**: Maps are not supported because for most languages, key orders are nondeterministic.
23 If you need to encode/decode maps of arbitrary key-value pairs, encode an array of {key,value} structs instead.
25 **Floating points**: Floating point number types are discouraged because [of reasons](http://gafferongames.com/networking-for-game-programmers/floating-point-determinism/). If you need to use them, use the field tag `wire:"unsafe"`.
27 **Enums**: Enum types are not supported in all languages, and they're simple enough to model as integers anyways.
31 Struct types can be automatically encoded with reflection. Unlike json-encoding, no field
32 name or type information is encoded. Field values are simply encoded in order.
41 "github.com/tendermint/go-wire"
52 foo := Foo{"my string", math.MaxUint32, []byte("my private bytes")}
54 buf, n, err := new(bytes.Buffer), int(0), error(nil)
55 wire.WriteBinary(foo, buf, &n, &err)
57 fmt.Printf("%X\n", buf.Bytes())
61 The above example prints:
64 01096D7920737472696E67FFFFFFFF, where
66 0109 is the varint encoding of the length of string "my string"
67 6D7920737472696E67 is the bytes of string "my string"
68 FFFFFFFF is the bytes for math.MaxUint32, a uint32
71 Note that the unexported "myPrivateBytes" isn't encoded.
73 ### An interface example
75 Here's an example with interfaces.
83 "github.com/tendermint/go-wire"
86 type Animal interface{}
87 type Dog struct{ Name string }
88 type Cat struct{ Name string }
89 type Cow struct{ Name string }
91 var _ = wire.RegisterInterface(
93 wire.ConcreteType{Dog{}, 0x01}, // type-byte of 0x01 for Dogs
94 wire.ConcreteType{Cat{}, 0x02}, // type-byte of 0x02 for Cats
95 wire.ConcreteType{Cow{}, 0x03}, // type-byte of 0x03 for Cows
105 buf, n, err := new(bytes.Buffer), int(0), error(nil)
106 wire.WriteBinary(animals, buf, &n, &err)
108 fmt.Printf("%X\n", buf.Bytes())
112 The above example prints:
115 0102010106536E6F6F70790301054461697379, where
117 0102 is the varint encoding of the length of the array
118 01 is the type-byte for a Dog
119 0106 is the varint encoding of the length of the Dog's name
120 536E6F6F7079 is the Dog's name "Snoopy"
121 03 is the type-byte for a Cow
122 0105 is the varint encoding of the length of the Cow's name
123 4461697379 is the Cow's name "Daisy"
126 ### A pointer example
128 Here's an example with pointers (and interfaces too).
136 "github.com/tendermint/go-wire"
139 type Animal interface{}
140 type Dog struct{ Name string }
141 type Cat struct{ Name string }
142 type Cow struct{ Name string }
144 var _ = wire.RegisterInterface(
146 wire.ConcreteType{Dog{}, 0x01}, // type-byte of 0x01 for Dogs
147 wire.ConcreteType{&Dog{}, 0x02}, // type-byte of 0x02 for Dog pointers
150 type MyStruct struct {
158 myStruct := MyStruct{
159 Field1: &Dog{"Snoopy"},
160 Field2: &Dog{"Smappy"},
164 buf, n, err := new(bytes.Buffer), int(0), error(nil)
165 wire.WriteBinary(myStruct, buf, &n, &err)
167 fmt.Printf("%X\n", buf.Bytes())
171 The above example prints:
174 020106536E6F6F7079010106536D6170707900, where
176 02 is the type-byte for a Dog pointer for Field1
177 0106 is the varint encoding of the length of the Dog's name
178 536E6F6F7079 is the Dog's name "Snoopy"
179 01 is a byte indicating a non-null pointer for Field2
180 0106 is the varint encoding of the length of the Dog's name
181 536D61707079 is the Dog's name "Smappy"
182 00 is a byte indicating a null pointer for Field3
185 Notice that in Field1, that the value is non-null is implied in the type-byte of 0x02.
186 While Golang lets you have nil-pointers as interface values, this is a Golang-specific feature that is absent in other OOP languages
187 such as Java. So, Go-Wire does not support nil-pointers for interface values. The following example would return an error:
190 myStruct := MyStruct{
191 Field1: (*Dog)(nil), // Error!
192 Field2: &Dog{"Smappy"}, // Ok!
193 Field3: (*Dog)(nil), // Ok!
196 buf, n, err := new(bytes.Buffer), int(0), error(nil)
197 wire.WriteBinary(myStruct, buf, &n, &err)
200 // Unexpected nil-pointer of type main.Dog for registered interface Animal.
201 // For compatibility with other languages, nil-pointer interface values are forbidden.