> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cosmos.network/llms.txt
> Use this file to discover all available pages before exploring further.

# BaseApp Overview

`BaseApp` is the execution engine of every Cosmos SDK chain. It implements [ABCI (Application Blockchain Interface)](/sdk/latest/learn/intro/sdk-app-architecture#abci-application-blockchain-interface), the protocol CometBFT uses to communicate with the application, and translates those calls into module execution, transaction processing, and state transitions.

Every Cosmos SDK chain embeds `BaseApp`. Your `app.go` creates a `BaseApp` instance, configures it with modules, keepers, and middleware, and the resulting struct is what CometBFT communicates with directly. `BaseApp` provides the base layer of execution infrastructure to your blockchain application. Without it, every chain would need to independently implement ABCI handling, signature verification, gas metering, message routing, block hook orchestration, and state commitment.

## Architectural position

`BaseApp` sits between CometBFT and the modules:

```
CometBFT (consensus engine)
    ↓  ABCI (InitChain, CheckTx, FinalizeBlock, Commit, ...)
BaseApp
    ↓  orchestrates block execution
ModuleManager
    ↓  dispatches to individual modules
Modules (x/auth, x/bank, x/staking, ...)
    ↓  read/write
State (KVStores)
```

CometBFT drives the block lifecycle by calling ABCI methods on `BaseApp`. `BaseApp` handles each call, delegating to registered lifecycle hooks and routing messages to the appropriate module handlers. Modules contain the business logic, and KVStores hold the resulting state.

## Key fields

[`BaseApp`](https://github.com/cosmos/cosmos-sdk/blob/main/baseapp/baseapp.go) is defined in `baseapp/baseapp.go`. It holds references to everything needed to run a chain:

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
type BaseApp struct {
    logger           log.Logger
    name             string                      // application name from abci.BlockInfo
    db               dbm.DB                      // common DB backend
    cms              storetypes.CommitMultiStore // Main (uncached) state
    storeLoader      StoreLoader                 // function to handle store loading
    grpcQueryRouter  *GRPCQueryRouter            // router for redirecting gRPC query calls
    msgServiceRouter *MsgServiceRouter           // router for redirecting Msg service messages
    txDecoder        sdk.TxDecoder               // unmarshal []byte into sdk.Tx
    mempool          mempool.Mempool
    anteHandler      sdk.AnteHandler             // ante handler for fee and auth
    postHandler      sdk.PostHandler             // post handler, optional
    // ...
    sealed           bool
    // ...
    chainID          string
    // ...
}
```

For a complete list of fields, see the [`BaseApp` struct definition](https://github.com/cosmos/cosmos-sdk/blob/main/baseapp/baseapp.go).

* `cms` (CommitMultiStore): the root state store. All module substores are mounted here, and all state reads and writes during block execution pass through it.
* `storeLoader`: a function that opens and mounts the individual module stores at application startup.
* `grpcQueryRouter`: routes incoming gRPC queries to the correct module's query handler.
* `msgServiceRouter`: routes each message in a transaction to the correct module's `MsgServer` handler.
* `txDecoder`: decodes raw transaction bytes from CometBFT into an `sdk.Tx`.
* `anteHandler`: runs before message execution to handle cross-cutting concerns: signature verification, sequence validation, and fee deduction.
* `postHandler`: optional middleware that runs after message execution — used for tasks such as tipping or post-execution state adjustments.
* `sealed`: set to `true` after `LoadLatestVersion` is called. Setter methods panic if called after sealing.

## Initialization and sealing

`BaseApp` enforces a configuration lifecycle: setter methods must be called before `LoadLatestVersion` is invoked. When `LoadLatestVersion` runs, it validates required components, initializes the check state, and sets `sealed` to `true`. Any setter called after sealing panics. On first launch, CometBFT calls `InitChain`. It stores `ConsensusParams` from the genesis file — block gas limit, max block size, evidence rules — in the `ParamStore`, where they can later be adjusted via on-chain governance. It initializes all volatile states by branching the root store, sets the block gas meter to infinite so genesis transactions are not gas-constrained, and calls the application's `initChainer`, which runs each module's `InitGenesis` to populate initial state. How this shapes the structure of `app.go` is covered in the next section.

## Transaction decoding

Transactions arrive from CometBFT as raw bytes. Before `BaseApp` can validate or execute them, it must decode them into the SDK's transaction type using the `TxDecoder`:

```
[]byte tx
   ↓
TxDecoder
   ↓
sdk.Tx
```

This step happens before the transaction enters the execution pipeline. Without it, `BaseApp` cannot inspect messages, run the `AnteHandler`, or route execution to the correct module.

## Execution modes

`BaseApp` does not execute everything against the same mutable state. It maintains branched, copy-on-write views of the committed root state for different execution contexts:

* `CheckTx` (`ExecModeCheck`): validates a transaction before it enters the mempool, without committing state.
* `FinalizeBlock` (`ExecModeFinalize`): executes transactions in a proposed block against a branched state that is committed at the end.
* `PrepareProposal` (`ExecModePrepareProposal`): runs when the node is the block proposer, assembling a candidate block. Executes against a branched state that is never committed.
* `ProcessProposal` (`ExecModeProcessProposal`): runs on every validator to validate an incoming proposal. Also executes against a branched state that is never committed.
* `Simulate` (`ExecModeSimulate`): runs a transaction for gas estimation without committing state.

This separation ensures that validation, proposal handling, and simulation cannot accidentally mutate committed application state.

## The transaction execution pipeline

When `BaseApp` processes a transaction, it runs through a structured pipeline:

```
RunTx
  ├─ DecodeTx       → raw bytes → sdk.Tx
  ├─ AnteHandler    → signatures, sequence, fees, gas setup
  ├─ RunMsgs        → route each message to the correct module handler
  └─ PostHandler    → optional post-execution middleware
```

If the `AnteHandler` fails, message execution does not begin. If any message fails, message execution reverts atomically; all message writes commit or none do.

## `AnteHandler`

The `AnteHandler` is middleware that runs before any message in a transaction executes. It verifies cryptographic signatures, validates and increments the account sequence number, deducts transaction fees, and sets up the gas meter for the transaction.

For the application wiring side, including `SetAnteHandler`, `HandlerOptions`, and constructor ordering, see [Mounting stores and setting hooks in `app.go`](/sdk/latest/learn/concepts/app-go#mounting-stores-and-setting-hooks).

If the `AnteHandler` fails, the transaction is rejected and its messages never execute. If the `AnteHandler` succeeds but a message later fails, the `AnteHandler`'s state writes, such as fee deduction and sequence increment for ordered transactions, are already flushed to `finalizeBlockState` and will be committed with the block. Fees are charged even for transactions whose messages fail.

`BaseApp.runTx()` also handles Go panics that occur during execution — for example, when a keeper encounters an invalid state. By default, panics are caught and logged as errors. Applications can register custom panic recovery logic via `BaseApp.AddRunTxRecoveryHandler`, which adds a `RecoveryHandler` to the chain. See [ADR-022](/sdk/latest/reference/architecture/adr-022-custom-panic-handling) and [`baseapp/recovery.go`](https://github.com/cosmos/cosmos-sdk/blob/release/v0.54.x/baseapp/recovery.go) for details.

## Message routing

When a transaction contains messages, `BaseApp` routes each one to the appropriate module handler using the `MsgServiceRouter`.

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
type MsgServiceRouter struct {
    routes map[string]MsgServiceHandler
    // ...
}
```

The routing process has three steps:

1. Registration: During app startup, each module calls `RegisterService`, which registers its message handlers keyed by message type URL (e.g., `/cosmos.bank.v1beta1.MsgSend`).
2. Lookup: At execution time, `Handler` looks up the registered handler for the incoming message's type URL.
3. Execution: The retrieved handler invokes the module's `MsgServer` implementation, which validates inputs, applies business rules, and updates state through the keeper.

This routing is entirely type-URL-based. Modules do not need to know about each other at the routing level; `BaseApp` is the neutral coordinator.

## Queries

For read-only access to application state, `BaseApp` uses the **`GRPCQueryRouter`** to route incoming gRPC queries to the correct module query service. Queries bypass the transaction execution pipeline and directly read committed state. They do not go through the `AnteHandler`, do not consume gas in the same way, and do not mutate state.

## Store management

`BaseApp` owns the `CommitMultiStore` that holds all module state. At app startup, each module registers its store key, and `BaseApp` mounts the corresponding store:

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
app.MountKVStores(keys)
```

Before executing each transaction, `BaseApp` creates a cached, copy-on-write view of the multistore. All writes during that transaction occur in the cache. If the transaction succeeds, the cache is flushed to the underlying store. If the transaction fails at any point, the cache is discarded and no state changes are applied.

## CheckTx and mempool validation

Before a transaction reaches block execution, it goes through `CheckTx`. `BaseApp` runs the `AnteHandler` in `CheckTx` mode to validate signatures, check sequence numbers, and verify fees. Each validator also enforces a configurable `minGasPrices` floor, and transactions offering less than the minimum gas price are rejected here as a spam protection measure. Transactions that fail `CheckTx` are rejected and do not enter the mempool.

`CheckTx` does not execute messages. It does run the `AnteHandler`, and if ante succeeds the resulting writes are persisted to `BaseApp`'s internal `CheckTx` state rather than to committed chain state. This is how the mempool tracks transaction validity before block execution. After each block commits, CometBFT triggers a recheck pass (`ReCheckTx`) that re-validates all pending mempool transactions against the new state, and any transactions that became invalid (for example, because their sequence number was consumed by a competing transaction) are evicted at this point.

## Coordinating block execution

When CometBFT calls `FinalizeBlock`, `BaseApp` runs the full block execution pipeline in order:

```
FinalizeBlock
  ├─ PreBlock    → module pre-block hooks
  ├─ BeginBlock  → module begin-block hooks
  ├─ For each transaction:
  │    ├─ AnteHandler   (signature verification, fee deduction, gas setup)
  │    ├─ Message routing and execution
  │    └─ Commit or revert (atomic per-transaction)
  └─ EndBlock    → module end-block hooks
       → returns AppHash
```

[`PreBlock`](/sdk/latest/learn/concepts/lifecycle#preblock) runs before any block logic. It handles changes that must take effect before the block begins, such as activating a chain upgrade or modifying consensus parameters.

[`BeginBlock`](/sdk/latest/learn/concepts/modules#beginblock) runs after [`PreBlock`](/sdk/latest/learn/concepts/lifecycle#preblock) and handles per-block housekeeping: minting inflation rewards, distributing staking rewards, resetting per-block counters.

[Transactions](/sdk/latest/learn/concepts/transactions) execute sequentially in block order. Message execution for each transaction is atomic: if any message fails, the message execution branch reverts. `AnteHandler` side effects may already have been applied.

[`EndBlock`](/sdk/latest/learn/concepts/modules#endblock) runs after all transactions. It handles logic that depends on the block's cumulative state — for example, tallying governance votes after all vote messages have been processed, or updating validator power after all delegation changes.

After `FinalizeBlock` completes, `BaseApp` computes and returns the app hash — the Merkle root of all committed state. See [App hash](/sdk/latest/learn/concepts/store#app-hash) for how it relates to the multistore and deterministic execution. When CometBFT subsequently calls `Commit`, `BaseApp` writes `finalizeBlockState` to the root store, resets `checkState` to the newly committed state, and clears `finalizeBlockState` to `nil` in preparation for the next block.

## Module Manager

`BaseApp` exposes `PreBlock`, `BeginBlock`, and `EndBlock` as lifecycle hook points. Every standard SDK application wires these to a `ModuleManager`, which holds the full set of registered modules and their execution ordering. When a hook fires, `ModuleManager` iterates its ordered module list and calls each module's corresponding hook in sequence. Ordering matters: some modules depend on others having already updated state before they run.

The `app.go` page shows how the application constructs the `ModuleManager`, wires it into `BaseApp`, and configures ordering in practice. See [Module Manager in `app.go`](/sdk/latest/learn/concepts/app-go#module-manager).

## Block proposal and vote extensions

[ABCI 2.0](/sdk/latest/guides/abci/abci#abci-20) added a proposal phase that runs during consensus rounds, before `FinalizeBlock` executes. `BaseApp` exposes four handlers for this phase, with default implementations wired at construction:

* `PrepareProposal`: called on the current block proposer to assemble a block from the mempool. The default selects transactions up to the block gas limit. Chains can override this to implement custom ordering, filtering, or injection of protocol-level transactions.
* `ProcessProposal`: called on every validator to validate an incoming proposal. The default accepts any structurally valid proposal. Chains that use `PrepareProposal` to inject data typically also override this to verify that data is present and valid.
* `ExtendVote` / `VerifyVoteExtension`: allow validators to attach arbitrary data to their precommit votes and verify other validators' extensions. One major use case is oracle price feeds: validators inject off-chain data into consensus so it becomes available on-chain at block start.

All four are configurable in `app.go` via `SetPrepareProposal`, `SetProcessProposal`, `SetExtendVoteHandler`, and `SetVerifyVoteExtensionHandler`. Chains that do not need custom behavior can leave the defaults in place.

## Putting it all together

`BaseApp` is the execution engine of a Cosmos SDK chain:

```
CometBFT → ABCI → BaseApp → Modules → State
```

It implements ABCI, coordinates the block lifecycle (`PreBlock` → `BeginBlock` → transactions → `EndBlock`), routes messages to module handlers via the `MsgServiceRouter`, routes queries via the `GRPCQueryRouter`, runs the `AnteHandler` before each transaction, and manages the multistore with copy-on-write caching for atomicity. State changes are committed at block end; validation and simulation run against branched state and never touch committed data.

The next section, [app.go Overview](/sdk/latest/learn/concepts/app-go), explains how `BaseApp` is instantiated, configured, and wired with modules to produce a complete, running chain.
