Project Setup and Code Generation
Directory Structure
Organize your protobuf files following this structure:Buf Configuration
proto/buf.yaml
:
proto/buf.gen.gogo.yaml
:
Generating Code
Message Annotations
Signer
Specifies which field(s) contain the transaction signer(s):Scalar Types
Scalar annotations provide type information for client libraries and validation:Address Types
Numeric Types
Complete Scalar Reference
Scalar Type | Go Type | Usage |
---|---|---|
cosmos.AddressString | sdk.AccAddress | User account addresses |
cosmos.ValidatorAddressString | sdk.ValAddress | Validator operator addresses |
cosmos.ConsensusAddressString | sdk.ConsAddress | Consensus key addresses |
cosmos.Int | sdk.Int | Arbitrary precision integers |
cosmos.Dec | sdk.Dec | Arbitrary precision decimals |
Interface Annotations
Implements Interface
Marks a message as implementing a specific interface:Accepts Interface
Specifies which interface anAny
field accepts:
- Type-safe
Any
unpacking - Client code generation
- Automatic validation
Versioning Annotations
Track when features were added for client compatibility:Method Added In
Field Added In
Message Added In
"[module] v[version]"
"cosmos-sdk v0.50.1"
"x/gov v2.0.0"
"ibc-go v8.0.0"
Gogoproto Annotations
Gogoproto provides Go-specific optimizations:Performance Optimizations
Common Gogoproto Options
Option | Effect | Usage |
---|---|---|
(gogoproto.nullable) = false | Non-pointer fields | Reduce allocations |
(gogoproto.equal) = true | Generate Equal() method | Equality checks |
(gogoproto.goproto_getters) = false | No getter methods | Direct field access |
(gogoproto.castrepeated) | Custom slice type | Type-safe collections |
(gogoproto.casttype) | Custom Go type | Custom implementations |
(gogoproto.customname) | Custom field name | Go naming conventions |
Amino Annotations (Legacy)
Amino annotations maintain backwards compatibility for signing:Amino is deprecated since v0.50. Only use for backwards compatibility.
Message Name
Field Annotations
Service Annotations
Message Service
Mark a service as a Msg service for transactions:Complete Example
Here’s a complete example using all annotation types:Best Practices
- Always use scalar annotations for addresses and numeric types
- Use
nullable=false
for required fields to reduce allocations - Implement interfaces with proper annotations for Any type safety
- Version your APIs with added_in annotations
- Document breaking changes with deprecated field markers
- Generate code regularly and commit .pb.go files
- Use buf for linting and breaking change detection
External Resources
- Protocol Buffers Documentation
- Buf Build - Modern protobuf tooling
- Gogoproto - Go-specific protobuf extensions
- Cosmos Proto - Cosmos SDK protobuf extensions
- Buf Registry - Cosmos SDK - Published SDK protos