Cosmos SDK Interview Questions - Easy

Easy-level Cosmos SDK interview questions covering chain code, SDK basics, and Ignite CLI.

Q1: What is Cosmos SDK and how does it work?

Answer:

Cosmos SDK is a framework for building blockchain applications in Go. It provides modular components that developers can combine to create custom blockchains.

Key Components:

  • ABCI (Application Blockchain Interface): Interface between application and consensus engine
  • Tendermint Core: Consensus and networking layer
  • Modules: Reusable components (bank, staking, governance)
  • Keepers: State management layer
  • Handlers: Process transactions

Architecture:

1β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
2β”‚  Application    β”‚  (Your custom logic)
3β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
4β”‚  Cosmos SDK     β”‚  (Modules, Keepers, Handlers)
5β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
6β”‚  ABCI           β”‚  (Interface)
7β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
8β”‚  Tendermint     β”‚  (Consensus & P2P)
9β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Q2: Explain the basic structure of a Cosmos SDK module.

Answer:

A module is the basic unit of functionality in Cosmos SDK. Each module has:

Structure:

 1// Module structure
 2module/
 3β”œβ”€β”€ keeper/
 4β”‚   └── keeper.go          // State management
 5β”œβ”€β”€ types/
 6β”‚   β”œβ”€β”€ keys.go            // Store keys
 7β”‚   β”œβ”€β”€ msgs.go            // Message types
 8β”‚   └── params.go          // Parameters
 9β”œβ”€β”€ handler.go             // Message handlers
10β”œβ”€β”€ querier.go             // Query handlers
11└── module.go              // Module definition

Example Module:

 1package bank
 2
 3import (
 4    sdk "github.com/cosmos/cosmos-sdk/types"
 5)
 6
 7// Keeper manages state
 8type Keeper struct {
 9    storeKey sdk.StoreKey
10    cdc      codec.Codec
11}
12
13// NewKeeper creates a new keeper
14func NewKeeper(cdc codec.Codec, storeKey sdk.StoreKey) Keeper {
15    return Keeper{
16        storeKey: storeKey,
17        cdc:      cdc,
18    }
19}
20
21// SendCoins transfers coins
22func (k Keeper) SendCoins(ctx sdk.Context, from, to sdk.AccAddress, amount sdk.Coins) error {
23    // Implementation
24    return nil
25}

Key Concepts:

  • Keeper: Manages access to module state
  • StoreKey: Identifies the store for this module
  • Context: Contains blockchain state (height, time, etc.)
  • Messages: User actions (transactions)
  • Queries: Read-only state access

Q3: How do you create a new blockchain with Ignite CLI?

Answer:

Ignite CLI is a tool for scaffolding Cosmos SDK blockchains.

Installation:

1curl https://get.ignite.com/cli! | bash

Create New Chain:

1# Create a new blockchain
2ignite scaffold chain github.com/user/mychain
3
4# This creates:
5# - Chain application code
6# - Module structure
7# - Configuration files
8# - Build scripts

Project Structure:

1mychain/
2β”œβ”€β”€ app/
3β”‚   └── app.go              # Application setup
4β”œβ”€β”€ cmd/
5β”‚   └── mychaind/           # Daemon binary
6β”œβ”€β”€ x/
7β”‚   └── mychain/             # Custom modules
8β”œβ”€β”€ proto/                   # Protocol buffers
9└── config.yml               # Ignite config

Add a Module:

1# Scaffold a new module
2ignite scaffold module mymodule
3
4# Add CRUD operations
5ignite scaffold list post title body --module mymodule

Run Chain:

1# Start local node
2ignite chain serve
3
4# Build and run
5ignite chain build
6./build/mychaind start

Key Ignite Commands:

  • ignite scaffold chain: Create new chain
  • ignite scaffold module: Add module
  • ignite scaffold list: Add CRUD operations
  • ignite scaffold message: Add transaction
  • ignite chain serve: Run development chain

Q4: What are messages and handlers in Cosmos SDK?

Answer:

Messages are user actions that modify state. Handlers process these messages.

Message Definition:

 1package types
 2
 3import (
 4    sdk "github.com/cosmos/cosmos-sdk/types"
 5)
 6
 7// MsgSend represents a send transaction
 8type MsgSend struct {
 9    FromAddress string
10    ToAddress   string
11    Amount      sdk.Coins
12}
13
14// ValidateBasic performs basic validation
15func (msg MsgSend) ValidateBasic() error {
16    if msg.FromAddress == "" {
17        return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "from address cannot be empty")
18    }
19    if msg.ToAddress == "" {
20        return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "to address cannot be empty")
21    }
22    if !msg.Amount.IsValid() {
23        return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "amount is invalid")
24    }
25    return nil
26}
27
28// GetSigners returns addresses that must sign
29func (msg MsgSend) GetSigners() []sdk.AccAddress {
30    from, _ := sdk.AccAddressFromBech32(msg.FromAddress)
31    return []sdk.AccAddress{from}
32}

Handler Implementation:

 1package keeper
 2
 3import (
 4    sdk "github.com/cosmos/cosmos-sdk/types"
 5    "github.com/user/mychain/x/mymodule/types"
 6)
 7
 8// HandleMsgSend processes send messages
 9func (k Keeper) HandleMsgSend(ctx sdk.Context, msg types.MsgSend) (*sdk.Result, error) {
10    // Convert addresses
11    from, err := sdk.AccAddressFromBech32(msg.FromAddress)
12    if err != nil {
13        return nil, err
14    }
15    
16    to, err := sdk.AccAddressFromBech32(msg.ToAddress)
17    if err != nil {
18        return nil, err
19    }
20    
21    // Transfer coins
22    err = k.SendCoins(ctx, from, to, msg.Amount)
23    if err != nil {
24        return nil, err
25    }
26    
27    // Emit event
28    ctx.EventManager().EmitEvent(
29        sdk.NewEvent(
30            types.EventTypeSend,
31            sdk.NewAttribute(types.AttributeKeyFrom, msg.FromAddress),
32            sdk.NewAttribute(types.AttributeKeyTo, msg.ToAddress),
33            sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Amount.String()),
34        ),
35    )
36    
37    return &sdk.Result{Events: ctx.EventManager().Events()}, nil
38}

Message Flow:

  1. User creates transaction with message
  2. Transaction is broadcast to network
  3. Validator receives transaction
  4. Handler processes message
  5. State is updated
  6. Event is emitted

Q5: How do you query state in Cosmos SDK?

Answer:

Queries are read-only operations that retrieve state.

Query Request:

 1package types
 2
 3// QueryBalanceRequest requests account balance
 4type QueryBalanceRequest struct {
 5    Address string
 6}
 7
 8// QueryBalanceResponse returns account balance
 9type QueryBalanceResponse struct {
10    Balance sdk.Coins
11}

Querier Implementation:

 1package keeper
 2
 3import (
 4    "github.com/cosmos/cosmos-sdk/types/query"
 5    "google.golang.org/grpc/codes"
 6    "google.golang.org/grpc/status"
 7)
 8
 9// Balance queries account balance
10func (k Keeper) Balance(ctx sdk.Context, req *types.QueryBalanceRequest) (*types.QueryBalanceResponse, error) {
11    if req == nil {
12        return nil, status.Error(codes.InvalidArgument, "invalid request")
13    }
14    
15    // Parse address
16    addr, err := sdk.AccAddressFromBech32(req.Address)
17    if err != nil {
18        return nil, status.Error(codes.InvalidArgument, "invalid address")
19    }
20    
21    // Get balance
22    balance := k.GetBalance(ctx, addr)
23    
24    return &types.QueryBalanceResponse{
25        Balance: balance,
26    }, nil
27}

Register Query:

1// In module.go
2func (am AppModule) RegisterQueryService(cfg module.Configurator) {
3    types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
4}

Query from CLI:

1# Query balance
2mychaind query bank balances <address>
3
4# Query with gRPC
5grpcurl -plaintext localhost:9090 cosmos.bank.v1beta1.Query/Balance \
6  '{"address": "cosmos1..."}'

Query Types:

  • gRPC queries: Standard queries via gRPC
  • ABCI queries: Direct store queries
  • REST queries: HTTP/REST API

Q6: What is a Keeper and how does it manage state?

Answer:

A Keeper is a module's interface to its state. It encapsulates all state access logic.

Keeper Structure:

 1package keeper
 2
 3import (
 4    sdk "github.com/cosmos/cosmos-sdk/types"
 5    "github.com/cosmos/cosmos-sdk/store/types"
 6)
 7
 8type Keeper struct {
 9    storeKey      sdk.StoreKey
10    cdc           codec.BinaryCodec
11    paramSpace    types.ParamSubspace
12    accountKeeper types.AccountKeeper
13    bankKeeper    types.BankKeeper
14}
15
16// NewKeeper creates a new keeper
17func NewKeeper(
18    cdc codec.BinaryCodec,
19    storeKey sdk.StoreKey,
20    paramSpace types.ParamSubspace,
21    ak types.AccountKeeper,
22    bk types.BankKeeper,
23) Keeper {
24    return Keeper{
25        storeKey:      storeKey,
26        cdc:           cdc,
27        paramSpace:    paramSpace,
28        accountKeeper: ak,
29        bankKeeper:    bk,
30    }
31}

State Access:

 1// Get retrieves value from store
 2func (k Keeper) Get(ctx sdk.Context, key []byte) []byte {
 3    store := ctx.KVStore(k.storeKey)
 4    return store.Get(key)
 5}
 6
 7// Set stores value
 8func (k Keeper) Set(ctx sdk.Context, key []byte, value []byte) {
 9    store := ctx.KVStore(k.storeKey)
10    store.Set(key, value)
11}
12
13// Has checks if key exists
14func (k Keeper) Has(ctx sdk.Context, key []byte) bool {
15    store := ctx.KVStore(k.storeKey)
16    return store.Has(key)
17}
18
19// Delete removes key
20func (k Keeper) Delete(ctx sdk.Context, key []byte) {
21    store := ctx.KVStore(k.storeKey)
22    store.Delete(key)
23}

Key Principles:

  • Encapsulation: Only keeper can access its store
  • Dependency Injection: Keepers can use other keepers
  • Store Keys: Each module has unique store key
  • Context: Provides access to current blockchain state

Q7: How do you add a new transaction type with Ignite?

Answer:

Scaffold Message:

1# Create a new message type
2ignite scaffold message create-post title body --module blog
3
4# This creates:
5# - Message type (types/msg_create_post.go)
6# - Handler (keeper/msg_server.go)
7# - CLI command (client/cli/tx_create_post.go)

Generated Message:

 1package types
 2
 3// MsgCreatePost defines the CreatePost message
 4type MsgCreatePost struct {
 5    Creator string
 6    Title   string
 7    Body    string
 8}
 9
10// NewMsgCreatePost creates a new MsgCreatePost instance
11func NewMsgCreatePost(creator string, title string, body string) *MsgCreatePost {
12    return &MsgCreatePost{
13        Creator: creator,
14        Title:   title,
15        Body:    body,
16    }
17}
18
19// ValidateBasic performs basic validation
20func (msg *MsgCreatePost) ValidateBasic() error {
21    if msg.Creator == "" {
22        return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "creator cannot be empty")
23    }
24    if msg.Title == "" {
25        return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "title cannot be empty")
26    }
27    return nil
28}
29
30// GetSigners returns the signers
31func (msg *MsgCreatePost) GetSigners() []sdk.AccAddress {
32    creator, err := sdk.AccAddressFromBech32(msg.Creator)
33    if err != nil {
34        panic(err)
35    }
36    return []sdk.AccAddress{creator}
37}

Handler Implementation:

 1package keeper
 2
 3func (k msgServer) CreatePost(goCtx context.Context, msg *types.MsgCreatePost) (*types.MsgCreatePostResponse, error) {
 4    ctx := sdk.UnwrapSDKContext(goCtx)
 5    
 6    // Create post
 7    post := types.Post{
 8        Creator: msg.Creator,
 9        Title:   msg.Title,
10        Body:    msg.Body,
11        Id:      k.AppendPost(ctx, types.Post{
12            Creator: msg.Creator,
13            Title:   msg.Title,
14            Body:    msg.Body,
15        }),
16    }
17    
18    // Emit event
19    ctx.EventManager().EmitEvent(
20        sdk.NewEvent(
21            types.EventTypePostCreated,
22            sdk.NewAttribute(types.AttributeKeyPostId, fmt.Sprintf("%d", post.Id)),
23        ),
24    )
25    
26    return &types.MsgCreatePostResponse{Id: post.Id}, nil
27}

Send Transaction:

 1# From CLI
 2mychaind tx blog create-post "My Title" "My Body" --from alice
 3
 4# From code
 5msg := types.NewMsgCreatePost(
 6    creator.String(),
 7    "My Title",
 8    "My Body",
 9)
10txResp, err := client.BroadcastTx(ctx, clientCtx, msg)

Q8: What are the main Cosmos SDK modules?

Answer:

Core Modules:

  1. Bank Module: Token transfers and balances

    • SendCoins: Transfer tokens
    • MintCoins: Create new tokens
    • BurnCoins: Destroy tokens
  2. Staking Module: Validator management

    • Delegate: Stake tokens
    • Undelegate: Unstake tokens
    • Redelegate: Move stake between validators
  3. Governance Module: On-chain governance

    • SubmitProposal: Create proposal
    • Vote: Vote on proposal
    • Deposit: Add deposit to proposal
  4. Distribution Module: Fee distribution

    • Distributes fees to validators
    • Handles validator rewards
  5. Slashing Module: Validator penalties

    • Slashes for downtime
    • Slashes for double-signing
  6. Auth Module: Account management

    • Account creation
    • Sequence numbers
    • Public keys

Using Modules:

 1// In app.go
 2app := simapp.NewSimApp(
 3    logger,
 4    db,
 5    nil,
 6    true,
 7    map[int64]bool{},
 8    simapp.DefaultNodeHome,
 9    simapp.MakeEncodingConfig(),
10    simapp.EmptyAppOptions{},
11    baseapp.SetChainID("mychain"),
12)

Module Dependencies:

  • Modules can depend on other modules
  • Access via keeper interfaces
  • Prevents circular dependencies

Q9: How do you test Cosmos SDK modules?

Answer:

Unit Testing:

 1package keeper_test
 2
 3import (
 4    "testing"
 5    "github.com/cosmos/cosmos-sdk/simapp"
 6    "github.com/stretchr/testify/require"
 7    "github.com/user/mychain/x/mymodule/keeper"
 8    "github.com/user/mychain/x/mymodule/types"
 9)
10
11func TestKeeper(t *testing.T) {
12    app := simapp.Setup(false)
13    ctx := app.BaseApp.NewContext(false, tmproto.Header{})
14    
15    keeper := app.MyModuleKeeper
16    
17    // Test operations
18    msg := types.MsgCreatePost{
19        Creator: "cosmos1...",
20        Title:   "Test",
21        Body:    "Body",
22    }
23    
24    _, err := keeper.CreatePost(ctx, &msg)
25    require.NoError(t, err)
26    
27    // Query
28    post, found := keeper.GetPost(ctx, 1)
29    require.True(t, found)
30    require.Equal(t, "Test", post.Title)
31}

Integration Testing:

 1func TestEndToEnd(t *testing.T) {
 2    app := simapp.Setup(false)
 3    ctx := app.BaseApp.NewContext(false, tmproto.Header{})
 4    
 5    // Create account
 6    acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr)
 7    app.AccountKeeper.SetAccount(ctx, acc)
 8    
 9    // Fund account
10    err := app.BankKeeper.SendCoins(
11        ctx,
12        moduleAcc,
13        addr,
14        sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000))),
15    )
16    require.NoError(t, err)
17    
18    // Execute transaction
19    msg := types.NewMsgCreatePost(addr.String(), "Title", "Body")
20    handler := keeper.NewHandler(app.MyModuleKeeper)
21    _, err = handler(ctx, msg)
22    require.NoError(t, err)
23}

Testing Tools:

  • simapp: Testing application
  • testify: Assertions
  • Mock: Mock keepers for isolation

Q10: What is the difference between ABCI and Cosmos SDK?

Answer:

ABCI (Application Blockchain Interface):

  • Purpose: Interface between application and consensus
  • Language: Protocol buffers
  • Level: Low-level interface

ABCI Methods:

 1// ABCI interface
 2type Application interface {
 3    // Consensus methods
 4    Info(RequestInfo) ResponseInfo
 5    InitChain(RequestInitChain) ResponseInitChain
 6    BeginBlock(RequestBeginBlock) ResponseBeginBlock
 7    DeliverTx(RequestDeliverTx) ResponseDeliverTx
 8    EndBlock(RequestEndBlock) ResponseEndBlock
 9    Commit() ResponseCommit
10    
11    // Query methods
12    Query(RequestQuery) ResponseQuery
13}

Cosmos SDK:

  • Purpose: Framework for building applications
  • Language: Go
  • Level: High-level framework

Relationship:

1β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
2β”‚ Application β”‚  (Your code)
3β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
4β”‚ Cosmos SDK  β”‚  (Modules, Keepers, Handlers)
5β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
6β”‚ ABCI        β”‚  (Interface)
7β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
8β”‚ Tendermint  β”‚  (Consensus)
9β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Differences:

  • ABCI: Protocol specification
  • Cosmos SDK: Implementation framework
  • ABCI: Works with any consensus engine
  • Cosmos SDK: Specifically for Tendermint

Usage:

  • Cosmos SDK implements ABCI
  • You build on Cosmos SDK
  • Tendermint uses ABCI to communicate

Related Snippets