Cosmos SDK
Master the Cosmos SDK for building custom, sovereign blockchains (app-chains) and decentralized applications with inter-blockchain communication (IBC). This skill covers module development, message handling, and client interactions for creating high-performance, interoperable chains tailored to specific use cases.
You are a seasoned architect of sovereign blockchains, deeply proficient in the Cosmos SDK. You've launched multiple app-chains, designed custom modules, and integrated them seamlessly into the broader IBC ecosystem, understanding the nuances of state transitions, consensus, and cross-chain communication. ## Key Points * `x/posts/` module directory structure. * `x/posts/types/message_create_post.go`: Defines the `MsgCreatePost` struct and its basic validation. * `x/posts/keeper/msg_server_create_post.go`: The handler for processing `MsgCreatePost`. * `x/posts/types/post.go`: A basic `Post` struct. * **Unbounded Iteration in BeginBlock/EndBlock.** Processing unbounded data structures during block lifecycle hooks creates block production delays that can halt the chain when data grows. * **Ignoring IBC Channel Versioning.** Deploying IBC-enabled modules without proper channel version negotiation causes silent failures when connecting to chains running different module versions. ## Quick Example ```bash # In your blogchain directory: ignite scaffold module posts ignite scaffold message create-post title body --module posts --signer creator ``` ```bash # Scaffold a query to list all posts ignite scaffold query list-post --module posts ```
skilldb get web3-development-skills/Cosmos SDKFull skill: 276 linesYou are a seasoned architect of sovereign blockchains, deeply proficient in the Cosmos SDK. You've launched multiple app-chains, designed custom modules, and integrated them seamlessly into the broader IBC ecosystem, understanding the nuances of state transitions, consensus, and cross-chain communication.
Core Philosophy
The Cosmos SDK embodies a philosophy of modularity, sovereignty, and interoperability. Instead of deploying smart contracts on a shared, general-purpose blockchain, you build application-specific blockchains—app-chains—that are fully optimized for their intended purpose. This approach grants unparalleled control over your chain's governance, economic model, and technical specifications, allowing for higher throughput, lower fees, and custom features not possible on multi-purpose chains.
The SDK abstracts away the complexities of networking and consensus, providing a robust framework to focus solely on your application's business logic. By leveraging the Inter-Blockchain Communication Protocol (IBC), your app-chain isn't isolated; it can trustlessly exchange value and data with other IBC-enabled chains, fostering a truly interconnected ecosystem. Embrace this modular architecture to create resilient, scalable, and specialized decentralized applications.
Setup
To begin building with Cosmos SDK, you'll need Go installed (version 1.20+ recommended). Then, install ignite CLI, the primary tool for scaffolding, developing, and deploying Cosmos SDK chains.
# Install Go (if not already installed)
# Follow instructions at https://go.dev/doc/install
# Install ignite CLI
curl https://get.ignite.com/cli! | bash
# Verify installation
ignite version
# Expected output: e.g., ignite version v0.27.0
Once ignite CLI is installed, you can scaffold your first chain.
# Scaffold a new chain named 'blogchain'
ignite scaffold chain blogchain --no-module
cd blogchain
# Install chain dependencies and build
go mod tidy
make install
# Initialize your chain for local development
blogchaind init mynode --chain-id blogchain
# Add a key for your local validator
blogchaind keys add validator
# Add genesis account for your validator
blogchaind add-genesis-account $(blogchaind keys show validator -a) 1000000000stake
# Set your validator as a genesis validator
blogchaind gentx validator 100000000stake --chain-id blogchain
# Collect genesis transactions
blogchaind collect-gentxs
# Start the chain
blogchaind start
This will start a local blockchain node, accessible via blogchaind CLI commands.
Key Techniques
1. Scaffolding a Custom Module and Message
Cosmos SDK applications are built as a collection of modules. Use ignite CLI to scaffold a new module and define a custom message within it. Let's create a posts module and a CreatePost message.
# In your blogchain directory:
ignite scaffold module posts
ignite scaffold message create-post title body --module posts --signer creator
This command generates:
x/posts/module directory structure.x/posts/types/message_create_post.go: Defines theMsgCreatePoststruct and its basic validation.x/posts/keeper/msg_server_create_post.go: The handler for processingMsgCreatePost.x/posts/types/post.go: A basicPoststruct.
2. Defining State and Implementing a Message Handler
After scaffolding, you define the actual state structure and implement the logic to mutate it.
Edit x/posts/types/post.go to define your Post structure, adding a unique ID.
// x/posts/types/post.go
package types
import (
"strconv"
)
type Post struct {
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
Body string `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"`
Creator string `protobuf:"bytes,4,opt,name=creator,proto3" json:"creator,omitempty"`
}
func (p Post) GetIdBytes() []byte {
return []byte(strconv.FormatUint(p.Id, 10))
}
Now, implement the CreatePost message handler in x/posts/keeper/msg_server_create_post.go. This function validates the message, creates a new Post object, stores it in the module's state, and emits events.
// x/posts/keeper/msg_server_create_post.go
package keeper
import (
"context"
"strconv"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"blogchain/x/posts/types"
)
func (k msgServer) CreatePost(goCtx context.Context, msg *types.MsgCreatePost) (*types.MsgCreatePostResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// Validate message (already done by scaffolded code, but good to remember)
if err := msg.ValidateBasic(); err != nil {
return nil, err
}
// Get the next post ID
id := k.GetNextPostID(ctx) // Assume this helper exists to get and increment ID
// Create the post object
post := types.Post{
Id: id,
Creator: msg.Creator,
Title: msg.Title,
Body: msg.Body,
}
// Store the post
store := ctx.KVStore(k.storeKey)
store.Set(types.KeyPrefix(types.PostKeyPrefix+strconv.FormatUint(post.Id, 10)), k.cdc.MustMarshal(&post))
// Increment the next post ID
k.SetNextPostID(ctx, id+1) // Assume this helper exists to set the next ID
// Emit an event
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator),
sdk.NewAttribute(types.EventTypeCreatePost, strconv.FormatUint(post.Id, 10)),
),
)
return &types.MsgCreatePostResponse{Id: post.Id}, nil
}
Note: You would need to implement GetNextPostID and SetNextPostID in x/posts/keeper/post.go or similar, using the KVStore to manage a global counter for post IDs.
3. Querying Chain State (gRPC)
To read data from your chain, you define gRPC queries. ignite CLI can scaffold a query for a list of items.
# Scaffold a query to list all posts
ignite scaffold query list-post --module posts
Now, implement the ListPost query in x/posts/keeper/grpc_query_list_post.go.
// x/posts/keeper/grpc_query_list_post.go
package keeper
import (
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"blogchain/x/posts/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/store/prefix"
)
func (k Keeper) ListPost(goCtx context.Context, req *types.QueryListPostRequest) (*types.QueryListPostResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}
ctx := sdk.UnwrapSDKContext(goCtx)
var posts []types.Post
store := ctx.KVStore(k.storeKey)
postStore := prefix.NewStore(store, types.KeyPrefix(types.PostKeyPrefix))
iterator := postStore.Iterator(nil, nil)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var post types.Post
k.cdc.MustUnmarshal(iterator.Value(), &post)
posts = append(posts, post)
}
return &types.QueryListPostResponse{Post: posts}, nil
}
4. Interacting with Your Chain (CLI & TS Client)
After building and running your chain (blogchaind start), you can interact using the generated CLI.
CLI Transaction:
# Add a new account for testing
blogchaind keys add alice
# Send some tokens to alice (from validator account)
blogchaind tx bank send validator alice 10000000stake --chain-id blogchain --fees 200stake --node tcp://localhost:26657 -y
# Create a post using alice's account
blogchaind tx posts create-post "My First Post" "This is the body of my first post on Blogchain." --from alice --chain-id blogchain --fees 200stake --node tcp://localhost:26657 -y
CLI Query:
# Query all posts
blogchaind query posts list-post --node tcp://localhost:26657
TypeScript Client (@cosmjs/stargate):
For frontend or external service integration, @cosmjs/stargate provides a powerful way to interact.
import { SigningStargateClient, StdFee, GasPrice } from "@cosmjs/stargate";
import { DirectSecp256k1Wallet } from "@cosmjs/proto-signing";
import { stringToPath } from "@cosmjs/bip39";
import { coins } from "@cosmjs/proto-signing";
// Define your custom message type URL and encoder
const typeUrl = "/blogchain.posts.MsgCreatePost";
const customMessages = {
createPost: {
typeUrl: typeUrl,
encode: (msg: { creator: string; title: string; body: string }, writer?: any) => {
// Your custom encoding logic for MsgCreatePost
const enc = new (require("protobufjs/minimal")).Writer(writer);
enc.string(msg.creator, 1); // creator is field 1
enc.string(msg.title, 2); // title is field 2
enc.string(msg.body, 3); // body is field 3
return enc;
},
// No decode needed for sending
},
};
async function createPost() {
// Implementation with mnemonic-based wallet setup and transaction signing
}
createPost().catch(console.error);
Anti-Patterns
-
Panicking in Message Handlers. Using
panic!orunwrap()in Cosmos SDK message handlers causes non-deterministic state corruption across nodes. Always return proper error types through thesdk.Errormechanism. -
Unbounded Iteration in BeginBlock/EndBlock. Processing unbounded data structures during block lifecycle hooks creates block production delays that can halt the chain when data grows.
-
Missing Input Validation on Custom Messages. Accepting user-provided parameters in custom transaction messages without bounds checking and type validation enables denial-of-service through malformed transactions.
-
Ignoring IBC Channel Versioning. Deploying IBC-enabled modules without proper channel version negotiation causes silent failures when connecting to chains running different module versions.
-
State Store Reads in Simulation. Performing expensive state store reads during transaction simulation (ante handlers) without caching causes gas estimation to be significantly slower than actual execution.
Install this skill directly: skilldb add web3-development-skills
Related Skills
Account Abstraction
Account Abstraction (AA) fundamentally changes how users interact with EVM chains by enabling smart contract accounts. This skill teaches you to build dApps with ERC-4337 compatible smart accounts, facilitating features like gas sponsorship, batch transactions, and flexible authentication methods.
Aptos Development
Develop dApps and smart contracts on the Aptos blockchain using the Move language, Aptos SDKs, and CLI tools. This skill covers building secure, scalable, and user-friendly web3 applications leveraging Aptos' high throughput and low latency.
Avalanche Development
This skill covers building decentralized applications and smart contracts on the Avalanche network, including its C-Chain, X-Chain, P-Chain, and custom Subnets. Learn to interact with the platform using SDKs, deploy EVM-compatible contracts, and manage cross-chain asset flows.
Base Development
Develop, deploy, and interact with smart contracts and dApps on Base, an Ethereum Layer 2 solution built on the OP Stack. Leverage its EVM compatibility for scalable and cost-efficient Web3 applications.
Cosmwasm Contracts
Develop, test, and deploy secure smart contracts on Cosmos SDK blockchains using Rust and CosmWasm.
Erc4337 Smart Accounts
Learn to build and interact with ERC-4337 Smart Accounts, enabling gasless transactions, multi-factor authentication, and custom validation logic without protocol-level changes.