Encoding
Cosmos SDK uses Protocol Buffers (protobuf) for encoding and decoding data structures. This provides efficient serialization, type safety, and language interoperability.Protocol Buffers
Why Protobuf?
- Efficient: Compact binary encoding
- Type-safe: Strongly typed messages
- Versioned: Supports schema evolution
- Cross-language: Works with multiple programming languages
- Deterministic: Same input produces same output
Protobuf Messages
Codecs
ProtoCodec
The main codec implementation using Protocol Buffers:codec/proto_codec.go
Codec Interface
codec/codec.go
Binary Encoding
Basic Marshaling
codec/proto_codec.go
Usage Example
Length-Prefixed Encoding
Useful for encoding multiple messages in sequence:codec/proto_codec.go
JSON Encoding
JSON Marshaling
codec/proto_codec.go
JSON Usage
Interface Handling
Interface Registry
Register interface implementations for proper encoding/decoding:codec/types/interface_registry.go
Any Type
ProtobufAny wraps interface types:
Working with Any
GoGo Protobuf Extensions
Cosmos SDK uses gogoproto for additional features:Custom Types
Repeated Casts
Common Options
Amino Compatibility
For backwards compatibility with Amino encoding:Store Encoding
Encoding for Storage
Key Encoding
Transaction Encoding
Tx Encoding
Decoding Transactions
Best Practices
- Use ProtoCodec - it’s the standard codec
- Register interfaces - always register interface implementations
- Handle Any types - properly pack/unpack interface types
- Use gogoproto options - customize generated code
- Version proto files - use v1beta1, v1, etc.
- Import shared types - reuse common message definitions
- Make encoding deterministic - same input must produce same output
- Use length prefixes - when encoding multiple messages
- Validate after unmarshal - check data integrity
- Cache codecs - don’t create new codecs repeatedly
Common Pitfalls
Nil Pointers
Interface Registration
Non-determinism
Related Concepts
- Queries - Using encoding in queries
- Transactions - Transaction encoding
- Storage - Encoding data for storage