In this section you will dive into the various functions and features of making transactions in the Interchain:
Transactions are objects created by end-users to trigger state changes in applications. They are comprised of metadata that defines a context, and one or more sdk.Msg
(opens new window) that trigger state changes within a module through the module’s Protobuf message service.
While there is much to explore as you journey through the stack, begin by understanding the transaction process from a user perspective:
TxBuilder
. TxBuilder
is the preferred way to generate a transaction.Deciding and signing are the main interactions of a user. Generating and broadcasting are attended to by the user interface and other automation.
Transaction objects are Cosmos SDK types that implement the Tx
(opens new window) interface. They contain the following methods:
GetMsgs
(opens new window): unwraps the transaction and returns a list of contained sdk.Msg
(opens new window). One transaction may have one or multiple messages.ValidateBasic
(opens new window): includes lightweight, stateless checks used by the ABCI messages' CheckTx
and DeliverTx
to make sure transactions are not invalid. For example, the Tx
(opens new window) ValidateBasic
(opens new window) function checks that its transactions are signed by the correct number of signers and that the fees do not exceed the user's maximum.This function is different from the ValidateBasic
(opens new window) functions for sdk.Msg
, which perform basic validity checks on messages only. For example, runTX
first runs ValidateBasic
on each message when it checks a transaction created from the auth module. Then it runs the auth module's AnteHandler
(opens new window), which calls ValidateBasic
for the transaction itself.
You should rarely manipulate a Tx
object directly. It is an intermediate type used for transaction generation. Developers usually use the TxBuilder
(opens new window) interface.
Transaction messages are not to be confused with ABCI messages, which define interactions between CometBFT and application layers.
Messages or sdk.Msg
(opens new window) are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define module messages by adding methods to the Protobuf Msg
service and defining a MsgServer
. Each sdk.Msg
is related to exactly one Protobuf Msg
service RPC defined inside each module's tx.proto
file. A Cosmos SDK app router automatically maps every sdk.Msg
to a corresponding RPC service, which routes it to the appropriate method. Protobuf generates a MsgServer
interface for each module's Msg
service and the module developer implements this interface.
This design puts more responsibility on module developers. It allows application developers to reuse common functionalities without having to repetitively implement state transition logic. While messages contain the information for the state transition logic, a transaction's other metadata and relevant information are stored in the TxBuilder
and Context
.
Every message in a transaction must be signed by the addresses specified by its GetSigners
(opens new window). The Cosmos SDK currently allows signing transactions in two different ways:
SIGN_MODE_DIRECT
(opens new window) (preferred): the most used implementation of the Tx
interface is the Protobuf Tx
(opens new window) message, which is used in SIGN_MODE_DIRECT
. Once signed by all signers, the BodyBytes
, AuthInfoBytes
, and Signatures
(opens new window) are gathered into TxRaw
(opens new window), whose serialized bytes (opens new window) are broadcast over the network.SIGN_MODE_LEGACY_AMINO_JSON
(opens new window): the legacy implementation of the Tx
interface is the StdTx
(opens new window) struct from x/auth
. The document signed by all signers is StdSignDoc
(opens new window), which is encoded into bytes (opens new window) using Amino JSON. Once all signatures are gathered into StdTx
, StdTx
is serialized using Amino JSON and these bytes are broadcast over the network. This method is being deprecated.The TxBuilder
interface contains metadata closely related to the generation of transactions. The end-user can freely set these parameters for the transaction to be generated:
Msgs
(opens new window): the array of messages included in the transaction.GasLimit
(opens new window): an option chosen by the users for how to calculate the gas amount they are willing to spend.Memo
(opens new window): a note or comment to send with the transaction.FeeAmount
(opens new window): the maximum amount the user is willing to pay in fees.TimeoutHeight
(opens new window): the block height until which the transaction is valid.Signatures
(opens new window): the array of signatures from all signers of the transaction.As there are currently two modes for signing transactions, there are also two implementations of TxBuilder
. There is a wrapper for SIGN_MODE_DIRECT
and the StdTxBuilder
(opens new window) for SIGN_MODE_LEGACY_AMINO_JSON
. The two possibilities should normally be hidden because end-users should prefer the overarching TxConfig
(opens new window) interface. TxConfig
is an app-wide (opens new window) configuration for managing transactions accessible from the context. Most importantly, it holds the information about whether to sign each transaction with SIGN_MODE_DIRECT
or SIGN_MODE_LEGACY_AMINO_JSON
.
A new TxBuilder
will be instantiated with the appropriate sign mode by calling txBuilder := txConfig.NewTxBuilder()
. TxConfig
will correctly encode the bytes either using SIGN_MODE_DIRECT
or SIGN_MODE_LEGACY_AMINO_JSON
once TxBuilder
is correctly populated with the setters of the fields described previously.
This is a pseudo-code snippet of how to generate and encode a transaction using the TxEncoder()
method:
Once the transaction bytes are generated and signed, there are three primary ways of broadcasting the transaction:
Application developers create entrypoints to the application by creating a command-line interface typically found in the application's ./cmd
folder, gRPC, and/or REST interface. These interfaces allow users to interact with the application.
For the command-line interface (CLI) module developers create subcommands to add as children to the application top-level transaction command TxCmd
(opens new window).
CLI commands bundle all the steps of transaction processing into one simple command:
The principal usage of gRPC is in the context of module query services. The Cosmos SDK also exposes other module-agnostic gRPC services. One of these is the Tx
service, which exposes a handful of utility functions such as simulating a transaction or querying a transaction, and also one method to broadcast transactions (opens new window).
See this code example (opens new window) for more insight.
Each gRPC method has its corresponding REST endpoint generated using gRPC-gateway. Rather than using gRPC, you can also use HTTP to broadcast the same transaction on the POST
/cosmos/tx/v1beta1/txs
endpoint.
See this code example (opens new window) for more details.
The three methods presented previously are higher abstractions on the CometBFT RPC /broadcast_tx_{async,sync,commit}
endpoints. You can use the Tendermint RPC endpoints (opens new window) to directly broadcast the transaction through CometBFT if you wish to.
CometBFT supports the following RPC protocols:
For more information on broadcasting with CometBFT RPC, see the documentation on Tendermint RPC transactions broadcast APIs (opens new window).
Previously, the ABCI application knew of a single transaction type: a checkers move with four int
. This is no longer sufficient with multiple games. You need to conform to its Tx
expectations, which means that you must create messages which are then placed into a transaction.
See the section on messages to learn how to do that.
To summarize, this section has explored: