Documentation

Overview

    Package json provides functions for marshaling and unmarshaling JSON in a format that is backwards-compatible with Amino JSON encoding. This mostly differs from encoding/json in encoding of integers (64-bit integers are encoded as strings, not numbers), and handling of interfaces (wrapped in an interface object with type/value keys).

    JSON tags (e.g. `json:"name,omitempty"`) are supported in the same way as encoding/json, as is custom marshaling overrides via the json.Marshaler and json.Unmarshaler interfaces.

    Note that not all JSON emitted by Tendermint is generated by this library; some is generated by encoding/json instead, and kept like that for backwards compatibility.

    Encoding of numbers uses strings for 64-bit integers (including unspecified ints), to improve compatibility with e.g. Javascript (which uses 64-bit floats for numbers, having 53-bit precision):

    int32(32)  // Output: 32
    uint32(32) // Output: 32
    int64(64)  // Output: "64"
    uint64(64) // Output: "64"
    int(64)    // Output: "64"
    uint(64)   // Output: "64"
    

    Encoding of other scalars follows encoding/json:

    nil   // Output: null
    true  // Output: true
    "foo" // Output: "foo"
    ""    // Output: ""
    

    Slices and arrays are encoded as encoding/json, including base64-encoding of byte slices with additional base64-encoding of byte arrays as well:

    []int64(nil)      // Output: null
    []int64{}         // Output: []
    []int64{1, 2, 3}  // Output: ["1", "2", "3"]
    []int32{1, 2, 3}  // Output: [1, 2, 3]
    []byte{1, 2, 3}   // Output: "AQID"
    [3]int64{1, 2, 3} // Output: ["1", "2", "3"]
    [3]byte{1, 2, 3}  // Output: "AQID"
    

    Maps are encoded as encoding/json, but only strings are allowed as map keys (nil maps are not emitted as null, to retain Amino backwards-compatibility):

    map[string]int64(nil)          // Output: {}
    map[string]int64{}             // Output: {}
    map[string]int64{"a":1,"b":2}  // Output: {"a":"1","b":"2"}
    map[string]int32{"a":1,"b":2}  // Output: {"a":1,"b":2}
    map[bool]int{true:1}           // Errors
    

    Times are encoded as encoding/json, in RFC3339Nano format, but requiring UTC time zone (with zero times emitted as "0001-01-01T00:00:00Z" as with encoding/json):

    time.Date(2020, 6, 8, 16, 21, 28, 123, time.FixedZone("UTC+2", 2*60*60))
    // Output: "2020-06-08T14:21:28.000000123Z"
    time.Time{}       // Output: "0001-01-01T00:00:00Z"
    (*time.Time)(nil) // Output: null
    

    Structs are encoded as encoding/json, supporting JSON tags and ignoring private fields:

    type Struct struct{
    	Name    string
    	Value   int32 `json:"value,omitempty"`
    	private bool
    }
    
    Struct{Name: "foo", Value: 7, private: true} // Output: {"Name":"foo","value":7}
    Struct{} // Output: {"Name":""}
    

    Registered types are encoded with type wrapper, regardless of whether they are given as interface or bare struct, but inside structs they are only emitted with type wrapper for interface fields (this follows Amino behavior):

    type Vehicle interface {
    	Drive() error
    }
    
    type Car struct {
    	Wheels int8
    }
    
    func (c *Car) Drive() error { return nil }
    
    RegisterType(&Car{}, "vehicle/car")
    
    Car{Wheels: 4}           // Output: {"type":"vehicle/car","value":{"Wheels":4}}
    &Car{Wheels: 4}          // Output: {"type":"vehicle/car","value":{"Wheels":4}}
    (*Car)(nil)              // Output: null
    Vehicle(Car{Wheels: 4})  // Output: {"type":"vehicle/car","value":{"Wheels":4}}
    Vehicle(nil)             // Output: null
    
    type Struct struct {
    	Car *Car
    	Vehicle Vehicle
    }
    
    Struct{Car: &Car{Wheels: 4}, Vehicle: &Car{Wheels: 4}}
    // Output: {"Car": {"Wheels: 4"}, "Vehicle": {"type":"vehicle/car","value":{"Wheels":4}}}
    

    Index

    Constants

    This section is empty.

    Variables

    This section is empty.

    Functions

    func Marshal

    func Marshal(v interface{}) ([]byte, error)

      Marshal marshals the value as JSON, using Amino-compatible JSON encoding (strings for 64-bit numbers, and type wrappers for registered types).

      func MarshalIndent

      func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)

        MarshalIndent marshals the value as JSON, using the given prefix and indentation.

        func RegisterType

        func RegisterType(_type interface{}, name string)

          RegisterType registers a type for Amino-compatible interface encoding in the global type registry. These types will be encoded with a type wrapper `{"type":"<type>","value":<value>}` regardless of which interface they are wrapped in (if any). If the type is a pointer, it will still be valid both for value and pointer types, but decoding into an interface will generate the a value or pointer based on the registered type.

          Should only be called in init() functions, as it panics on error.

          func Unmarshal

          func Unmarshal(bz []byte, v interface{}) error

            Unmarshal unmarshals JSON into the given value, using Amino-compatible JSON encoding (strings for 64-bit numbers, and type wrappers for registered types).

            Types

            This section is empty.