### Messages Users can create messages containing arbitrary information by implementing the `Msg` interface: ```go type Msg interface { // Return the message type. // Must be alphanumeric or empty. Type() string // Get the canonical byte representation of the Msg. GetSignBytes() []byte // ValidateBasic does a simple validation check that // doesn't require access to any other information. ValidateBasic() error // Signers returns the addrs of signers that must sign. // CONTRACT: All signatures must be present to be valid. // CONTRACT: Returns addrs in some deterministic order. GetSigners() []Address } ``` Messages must specify their type via the `Type()` method. The type should correspond to the messages handler, so there can be many messages with the same type. Messages must also specify how they are to be authenticated. The `GetSigners()` method return a list of addresses that must sign the message, while the `GetSignBytes()` method returns the bytes that must be signed for a signature to be valid. Addresses in the SDK are arbitrary byte arrays that are hex-encoded when displayed as a string or rendered in JSON. Messages can specify basic self-consistency checks using the `ValidateBasic()` method to enforce that message contents are well formed before any actual logic begins. For instance, the `Basecoin` message types are defined in `x/bank/tx.go`: ```go type MsgSend struct { Inputs []Input `json:"inputs"` Outputs []Output `json:"outputs"` } type MsgIssue struct { Banker sdk.Address `json:"banker"` Outputs []Output `json:"outputs"` } ``` Each specifies the addresses that must sign the message: ```go func (msg MsgSend) GetSigners() []sdk.Address { addrs := make([]sdk.Address, len(msg.Inputs)) for i, in := range msg.Inputs { addrs[i] = in.Address } return addrs } func (msg MsgIssue) GetSigners() []sdk.Address { return []sdk.Address{msg.Banker} } ```