在上一节中,你已经了解到,账户 使用数字签名和序列号来授权链上的活动。账户提供身份与权限,但真正用于在链上授权并执行逻辑的机制是交易。

与链交互

Cosmos SDK 区块链是一个确定性的状态机。它的状态只有在交易被执行并提交到区块时才会发生变化。 用户和应用主要通过两种方式与区块链交互:
  • 交易 会修改状态,并被包含在区块中。当用户想要改变某些内容时(转移代币、委托质押、提交治理提案),他们会提交一笔交易。
  • 查询 会读取状态,不会被包含在区块中。当用户想要查看某些内容时(检查余额、查看委托、读取提案详情),他们会执行一次查询。
只有交易会影响共识状态。

交易

交易是一个带有签名的容器,承载一个或多个要在区块链上执行的动作。 一笔交易包含:
  • 消息:一个或多个你想执行的动作(发送代币、委托质押、对提案投票)
  • 签名:证明你授权这些动作的密码学凭证
  • 序列号:防止他人重复提交你的交易(重放保护)
  • Gas 上限:你愿意为执行消耗的最大计算资源
  • 费用:你为处理该交易支付的成本
交易本身并不定义业务逻辑。相反,它负责封装改变状态的意图(消息)、证明授权(签名),以及指定执行限制(gas 和费用)。你可以把交易看作寄给区块链的一个信封,里面装着包含指令的消息,用签名证明真实性,再贴上邮票支付邮资。
交易
  ├── 消息 1
  ├── 消息 2
  ├── ...
  ├── 签名
  ├── 序列号
  ├── Gas 上限
  └── 费用
在 Cosmos SDK 中,账户元数据和交易授权由 x/auth 模块处理。交易的构造与编码则通过 SDK 的交易系统进行配置(通常通过 x/auth/tx)。

消息

消息(sdk.Msg)是交易中的实际指令。每条消息都由特定模块定义,并表示一个单独动作。消息位于该模块的 types 包中(例如 x/bank/types 或 x/staking/types)。模块会定义自己支持哪些消息,以及执行这些消息的规则。交易提供带有签名和费用的信封,而消息则定义要执行的具体动作。 示例包括 MsgSend(转移代币)、MsgDelegate(委托质押)和 MsgVote(对提案投票)。 如果一笔交易包含多条消息,它们会按顺序执行。详见下文的消息执行顺序与原子性。

消息如何定义

在 Cosmos SDK 中,消息通过各模块的 tx.proto 文件 使用 Protocol Buffers(protobuf) 来定义,这种方式提供了确定性序列化、向后兼容性以及跨语言支持。每条消息都定义在一个 .proto 文件中,其中指定其字段、数据类型和唯一标识符。基于该模式会生成相应代码,用于构造、序列化和校验消息。 下面是一个 JSON 格式的交易示例:
{
  "body": {
    "messages": [
      {
        "@type": "/cosmos.bank.v1beta1.MsgSend",
        "from_address": "cosmos1...",
        "to_address": "cosmos1...",
        "amount": [{"denom": "uatom", "amount": "1000000"}]
      }
    ],
    "memo": "",
    "timeout_height": "0",
    "extension_options": [],
    "non_critical_extension_options": []
  },
  "auth_info": {
    "signer_infos": [
      {
        "public_key": {
          "@type": "/cosmos.crypto.secp256k1.PubKey",
          "key": "A..."
        },
        "mode_info": {"single": {"mode": "SIGN_MODE_DIRECT"}},
        "sequence": "0"
      }
    ],
    "fee": {
      "amount": [{"denom": "uatom", "amount": "500"}],
      "gas_limit": "200000",
      "payer": "",
      "granter": ""
    }
  },
  "signatures": ["MEUCIQDx..."]
}
这笔交易将 1 ATOM(1,000,000 uatom)从一个账户转移到另一个账户。你可以在 body.messages 数组中看到消息,在 auth_info.signer_infos 中看到发送者的公钥和序列号,在 auth_info.fee 中看到费用和 Gas 上限,并在 signatures 数组中看到密码学签名。 在广播时,这段 JSON 会使用 protobuf 序列化为字节,以确保每个验证者都以完全相同的方式解释这笔交易。

消息执行顺序与原子性

当一笔交易包含多条消息时,它们会按照在交易中出现的顺序执行。 例如,一笔交易可能会:
  1. 向另一个账户发送代币。
  2. 将这些代币委托给某个验证者。
如果顺序反过来,委托可能会因为余额不足而失败。 在执行时,交易中的消息会依次应用。只有当所有消息都成功执行时,整笔交易才会成功。 概念上:
交易
  ├── Msg 1 → 执行
  ├── Msg 2 → 执行
  ├── Msg 3 → 执行
如果任何一条消息失败,交易会返回错误,并且该交易内所有消息执行产生的写入都不会被提交。 交易内的消息执行是原子的:要么全部提交,要么全部不提交。交易生命周期 页面会更详细地介绍这条执行流水线。
在 v0.53 中,交易支持可选的 unordered 模式。当 unordered=true 时,常规的按签名者序列号检查会被绕过,重放保护改由 timeout_timestamp 加上 x/auth 中的无序 nonce 跟踪来处理。这使得无需协调序列号即可进行即发即弃和并发交易提交。无序交易必须设置 timeout_timestamp,并且序列号必须为 0。关于客户端如何构造和提交此类交易,参见生成无序交易。

区块与交易

区块链可以理解为一系列区块组成的序列。每个区块都包含一个有序的交易列表。 当一个新区块被提交时:
  1. 区块中的每笔交易都会被应用到当前状态。
  2. 每笔交易都会按顺序执行其消息。
  3. 各模块更新自己负责的那部分状态。
  4. 更新后的状态成为下一个区块的起始状态。
概念上:
状态₀
  ↓ 应用区块 1(Tx₁、Tx₂、Tx₃)
状态₁
  ↓ 应用区块 2(Tx₄、Tx₅)
状态₂
  ↓ 应用区块 3(...)
状态₃
通过这种方式,区块链就是一串完全由交易驱动的确定性状态转换序列。 区块对交易进行分组,交易驱动执行,而执行更新状态。

查询

查询是在不修改区块链状态的情况下获取数据。 查询是只读的。它们不需要签名,不会被包含在区块中,也不会影响共识状态。模块通过 query.proto 文件 使用 protobuf 定义查询服务,并通过 gRPC 和 REST 暴露出来。 例如:
  • 查询账户余额(x/bank 模块)
  • 查询质押委托(x/staking 模块)
  • 查询治理提案详情(x/gov 模块)

交易与查询流程

交易流程查询流程
用户
↓ 签名
交易
↓ 包含
消息
↓ 由其处理
模块
↓ 更新
状态
用户
↓
查询
↓
模块
↓
状态(只读)
交易会修改区块链。消息定义要发生什么修改。模块按顺序执行这些修改。查询则允许任何人观察最终产生的状态。要在一条实际运行的链上查看这一流程,参见 Quickstart 教程。 下一节交易生命周期会沿着一笔交易从广播、校验、纳入区块、执行到状态提交的全过程进行说明,展示这些组件在实践中如何协同工作。
In the previous section, you learned that accounts authorize activity on a chain using digital signatures and sequence numbers. Accounts provide identity and permission, but transactions are the actual mechanism that authorizes and executes logic on the chain.

Interacting with a chain

A Cosmos SDK blockchain is a deterministic state machine. Its state changes only when transactions are executed and committed in blocks. Users and applications interact with the blockchain in two fundamental ways:
  • Transactions modify state and are included in blocks. When a user wants to change something (transfer tokens, delegate stake, submit a governance proposal), they submit a transaction.
  • Queries read state and are not included in blocks. When a user wants to inspect something (check a balance, view delegations, read proposal details), they perform a query.
Only transactions affect consensus state.

Transactions

A transaction is a signed container that carries one or more actions to be executed on the blockchain. A transaction includes:
  • Messages: one or more actions you want to execute (send tokens, delegate stake, vote on a proposal)
  • Signatures: cryptographic proof that you authorize these actions
  • Sequence number: prevents someone from resubmitting your transaction (replay protection)
  • Gas limit: the maximum computational resources you’re willing to spend
  • Fees: what you pay for the transaction to be processed
The transaction itself does not define business logic. Instead, it packages intent (messages) to change state, proves authorization (signatures), and specifies execution limits (gas and fees). You can think of a transaction as an envelope you send to the blockchain, with a message inside containing instructions, a signature to prove authenticity, and a stamp to pay for postage.
Transaction
  ├── Message 1
  ├── Message 2
  ├── ...
  ├── Signature(s)
  ├── Sequence
  ├── Gas limit
  └── Fees
In the Cosmos SDK, account metadata and transaction authorization are handled by the x/auth module. Transaction construction and encoding are configured through the SDK’s transaction system (commonly via x/auth/tx).

Messages

A message (sdk.Msg) is the actual instruction inside a transaction. Each message is defined by a specific module and represents a single action. Messages are located in that module’s types package (like x/bank/types or x/staking/types). Modules define which messages they support and the rules for executing them. While the transaction provides the envelope with signatures and fees, the message defines the specific action to execute. Examples include MsgSend (transfer tokens), MsgDelegate (delegate stake), and MsgVote (vote on proposals). If a transaction contains multiple messages, they execute in order. See Message execution and atomicity below for details.

How messages are defined

Messages in the Cosmos SDK are defined in each module’s tx.proto file using Protocol Buffers (protobuf), which provides deterministic serialization, backward compatibility, and cross-language support. Each message is defined in a .proto file that specifies its fields, data types, and unique identifiers. From this schema, code is generated that allows the message to be constructed, serialized, and validated. Here’s an example of a transaction in JSON format:
{
  "body": {
    "messages": [
      {
        "@type": "/cosmos.bank.v1beta1.MsgSend",
        "from_address": "cosmos1...",
        "to_address": "cosmos1...",
        "amount": [{"denom": "uatom", "amount": "1000000"}]
      }
    ],
    "memo": "",
    "timeout_height": "0",
    "extension_options": [],
    "non_critical_extension_options": []
  },
  "auth_info": {
    "signer_infos": [
      {
        "public_key": {
          "@type": "/cosmos.crypto.secp256k1.PubKey",
          "key": "A..."
        },
        "mode_info": {"single": {"mode": "SIGN_MODE_DIRECT"}},
        "sequence": "0"
      }
    ],
    "fee": {
      "amount": [{"denom": "uatom", "amount": "500"}],
      "gas_limit": "200000",
      "payer": "",
      "granter": ""
    }
  },
  "signatures": ["MEUCIQDx..."]
}
This transaction transfers 1 ATOM (1,000,000 uatom) from one account to another. You can see the message in the body.messages array, the sender’s public key and sequence in auth_info.signer_infos, the fee and gas limit in auth_info.fee, and the cryptographic signature in the signatures array. When broadcast, this JSON is serialized into bytes using protobuf, ensuring every validator interprets the transaction identically.

Message execution and atomicity

When a transaction contains multiple messages, they are executed in the order they appear in the transaction. For example, a transaction might:
  1. Send tokens to another account.
  2. Delegate those tokens to a validator.
If the order were reversed, the delegation could fail due to insufficient balance. At execution time, messages inside a transaction are applied sequentially. The transaction succeeds only if all messages execute successfully. Conceptually:
Transaction
  ├── Msg 1 → execute
  ├── Msg 2 → execute
  ├── Msg 3 → execute
If any message fails, the transaction returns an error and none of the message execution writes from that transaction are committed. Message execution inside a transaction is atomic: all messages commit or none do. The transaction lifecycle page covers this execution pipeline in more detail.
In v0.53, transactions support an optional unordered mode. When unordered=true, the normal per-signer sequence check is bypassed and replay protection is handled through timeout_timestamp plus unordered nonce tracking in x/auth. This enables fire-and-forget and concurrent transaction submission without coordinating sequence numbers. Unordered transactions must have a timeout_timestamp set and a sequence of 0. For how clients build and submit them, see Generating an Unordered Transaction.

Blocks and transactions

A blockchain can be understood as a sequence of blocks. Each block contains an ordered list of transactions. When a new block is committed:
  1. Each transaction in the block is applied to the current state.
  2. Each transaction executes its messages in order.
  3. Modules update their portion of state.
  4. The resulting state becomes the starting point for the next block.
Conceptually:
State₀
  ↓ apply Block 1 (Tx₁, Tx₂, Tx₃)
State₁
  ↓ apply Block 2 (Tx₄, Tx₅)
State₂
  ↓ apply Block 3 (...)
State₃
In this way, the blockchain is a deterministic sequence of state transitions driven entirely by transactions. Blocks group transactions, transactions drive execution, and execution updates state.

Queries

A query retrieves data from the blockchain’s state without modifying it. Queries are read-only. They don’t require signatures, aren’t included in blocks, and don’t affect consensus state. Modules define query services using protobuf in a query.proto file, exposed over gRPC and REST. For example:
  • Query an account’s balance (the x/bank module)
  • Query staking delegations (the x/staking module)
  • Query governance proposal details (the x/gov module)

Transaction and query flow

Transaction FlowQuery Flow
User
↓ signs
Transaction
↓ contains
Message(s)
↓ handled by
Module(s)
↓ update
State
User
↓
Query
↓
Module
↓
State (read-only)
Transactions modify the blockchain. Messages define what modifications occur. Modules execute those modifications in order. Queries allow anyone to observe the resulting state. To see this flow in action with a working chain, see the Quickstart tutorial. The next section, Transaction Lifecycle, follows a transaction from broadcast through validation, block inclusion, execution, and state commitment to show how these components work together in practice.