Synopsis Modules generally handle a subset of the state and, as such, they need to define the related subset of the genesis file as well as methods to initialize, verify and export it.
Pre-requisite Readings

Type Definition

The subset of the genesis state defined from a given module is generally defined in a genesis.proto file (more info on how to define protobuf messages). The struct defining the module’s subset of the genesis state is usually called GenesisState and contains all the module-related values that need to be initialized during the genesis process. See an example of GenesisState protobuf message definition from the auth module:
/ Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/auth/v1beta1/genesis.proto
Next we present the main genesis-related methods that need to be implemented by module developers in order for their module to be used in Cosmos SDK applications.

DefaultGenesis

The DefaultGenesis() method is a simple method that calls the constructor function for GenesisState with the default value for each parameter. See an example from the auth module:
package auth

import (
    
	"context"
    "encoding/json"
    "fmt"

	abci "github.com/cometbft/cometbft/abci/types"
	gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
    "cosmossdk.io/depinject"

	authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec"
    "cosmossdk.io/core/address"
    "cosmossdk.io/core/appmodule"

	modulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
    "cosmossdk.io/core/store"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/types/module"
	simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
    "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
    "github.com/cosmos/cosmos-sdk/x/auth/exported"
    "github.com/cosmos/cosmos-sdk/x/auth/keeper"
    "github.com/cosmos/cosmos-sdk/x/auth/simulation"
    "github.com/cosmos/cosmos-sdk/x/auth/types"
)

/ ConsensusVersion defines the current x/auth module consensus version.
const (
	ConsensusVersion = 5
	GovModuleName    = "gov"
)

var (
	_ module.AppModule           = AppModule{
}
	_ module.AppModuleBasic      = AppModuleBasic{
}
	_ module.AppModuleSimulation = AppModule{
}
)

/ AppModuleBasic defines the basic application module used by the auth module.
type AppModuleBasic struct {
    ac address.Codec
}

/ Name returns the auth module's name.
func (AppModuleBasic)

Name()

string {
    return types.ModuleName
}

/ RegisterLegacyAminoCodec registers the auth module's types for the given codec.
func (AppModuleBasic)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    types.RegisterLegacyAminoCodec(cdc)
}

/ DefaultGenesis returns default genesis state as raw bytes for the auth
/ module.
func (AppModuleBasic)

DefaultGenesis(cdc codec.JSONCodec)

json.RawMessage {
    return cdc.MustMarshalJSON(types.DefaultGenesisState())
}

/ ValidateGenesis performs genesis state validation for the auth module.
func (AppModuleBasic)

ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage)

error {
    var data types.GenesisState
    if err := cdc.UnmarshalJSON(bz, &data); err != nil {
    return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
}

return types.ValidateGenesis(data)
}

/ RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the auth module.
func (AppModuleBasic)

RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *gwruntime.ServeMux) {
    if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
    panic(err)
}
}

/ GetTxCmd returns the root tx command for the auth module.
func (AppModuleBasic)

GetTxCmd() *cobra.Command {
    return nil
}

/ GetQueryCmd returns the root query command for the auth module.
func (ab AppModuleBasic)

GetQueryCmd() *cobra.Command {
    return cli.GetQueryCmd(ab.ac)
}

/ RegisterInterfaces registers interfaces and implementations of the auth module.
func (AppModuleBasic)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    types.RegisterInterfaces(registry)
}

/ AppModule implements an application module for the auth module.
type AppModule struct {
    AppModuleBasic

	accountKeeper     keeper.AccountKeeper
	randGenAccountsFn types.RandomGenesisAccountsFn

	/ legacySubspace is used solely for migration of x/params managed parameters
	legacySubspace exported.Subspace
}

var _ appmodule.AppModule = AppModule{
}

/ IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (am AppModule)

IsOnePerModuleType() {
}

/ IsAppModule implements the appmodule.AppModule interface.
func (am AppModule)

IsAppModule() {
}

/ NewAppModule creates a new AppModule object
func NewAppModule(cdc codec.Codec, accountKeeper keeper.AccountKeeper, randGenAccountsFn types.RandomGenesisAccountsFn, ss exported.Subspace)

AppModule {
    return AppModule{
    AppModuleBasic:    AppModuleBasic{
    ac: accountKeeper.AddressCodec()
},
		accountKeeper:     accountKeeper,
		randGenAccountsFn: randGenAccountsFn,
		legacySubspace:    ss,
}
}

/ Name returns the auth module's name.
func (AppModule)

Name()

string {
    return types.ModuleName
}

/ RegisterServices registers a GRPC query service to respond to the
/ module-specific GRPC queries.
func (am AppModule)

RegisterServices(cfg module.Configurator) {
    types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.accountKeeper))

types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServer(am.accountKeeper))
    m := keeper.NewMigrator(am.accountKeeper, cfg.QueryServer(), am.legacySubspace)
    if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil {
    panic(fmt.Sprintf("failed to migrate x/%s from version 1 to 2: %v", types.ModuleName, err))
}
    if err := cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3); err != nil {
    panic(fmt.Sprintf("failed to migrate x/%s from version 2 to 3: %v", types.ModuleName, err))
}
    if err := cfg.RegisterMigration(types.ModuleName, 3, m.Migrate3to4); err != nil {
    panic(fmt.Sprintf("failed to migrate x/%s from version 3 to 4: %v", types.ModuleName, err))
}
    if err := cfg.RegisterMigration(types.ModuleName, 4, m.Migrate4To5); err != nil {
    panic(fmt.Sprintf("failed to migrate x/%s from version 4 to 5", types.ModuleName))
}
}

/ InitGenesis performs genesis initialization for the auth module. It returns
/ no validator updates.
func (am AppModule)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
    var genesisState types.GenesisState
	cdc.MustUnmarshalJSON(data, &genesisState)

am.accountKeeper.InitGenesis(ctx, genesisState)

return []abci.ValidatorUpdate{
}
}

/ ExportGenesis returns the exported genesis state as raw bytes for the auth
/ module.
func (am AppModule)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

json.RawMessage {
    gs := am.accountKeeper.ExportGenesis(ctx)

return cdc.MustMarshalJSON(gs)
}

/ ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule)

ConsensusVersion()

uint64 {
    return ConsensusVersion
}

/ AppModuleSimulation functions

/ GenerateGenesisState creates a randomized GenState of the auth module
func (am AppModule)

GenerateGenesisState(simState *module.SimulationState) {
    simulation.RandomizedGenState(simState, am.randGenAccountsFn)
}

/ ProposalMsgs returns msgs used for governance proposals for simulations.
func (AppModule)

ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg {
    return simulation.ProposalMsgs()
}

/ RegisterStoreDecoder registers a decoder for auth module's types
func (am AppModule)

RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {
    sdr[types.StoreKey] = simtypes.NewStoreDecoderFuncFromCollectionsSchema(am.accountKeeper.Schema)
}

/ WeightedOperations doesn't return any auth module operation.
func (AppModule)

WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation {
    return nil
}

/
/ App Wiring Setup
/

func init() {
    appmodule.Register(&modulev1.Module{
},
		appmodule.Provide(ProvideAddressCodec),
		appmodule.Provide(ProvideModule),
	)
}

/ ProvideAddressCodec provides an address.Codec to the container for any
/ modules that want to do address string <> bytes conversion.
func ProvideAddressCodec(config *modulev1.Module)

address.Codec {
    return authcodec.NewBech32Codec(config.Bech32Prefix)
}

type ModuleInputs struct {
    depinject.In

	Config       *modulev1.Module
	StoreService store.KVStoreService
	Cdc          codec.Codec

	RandomGenesisAccountsFn types.RandomGenesisAccountsFn `optional:"true"`
	AccountI                func()

sdk.AccountI           `optional:"true"`

	/ LegacySubspace is used solely for migration of x/params managed parameters
	LegacySubspace exported.Subspace `optional:"true"`
}

type ModuleOutputs struct {
    depinject.Out

	AccountKeeper keeper.AccountKeeper
	Module        appmodule.AppModule
}

func ProvideModule(in ModuleInputs)

ModuleOutputs {
    maccPerms := map[string][]string{
}
    for _, permission := range in.Config.ModuleAccountPermissions {
    maccPerms[permission.Account] = permission.Permissions
}

	/ default to governance authority if not provided
    authority := types.NewModuleAddress(GovModuleName)
    if in.Config.Authority != "" {
    authority = types.NewModuleAddressOrBech32Address(in.Config.Authority)
}
    if in.RandomGenesisAccountsFn == nil {
    in.RandomGenesisAccountsFn = simulation.RandomGenesisAccounts
}
    if in.AccountI == nil {
    in.AccountI = types.ProtoBaseAccount
}
    k := keeper.NewAccountKeeper(in.Cdc, in.StoreService, in.AccountI, maccPerms, in.Config.Bech32Prefix, authority.String())
    m := NewAppModule(in.Cdc, k, in.RandomGenesisAccountsFn, in.LegacySubspace)

return ModuleOutputs{
    AccountKeeper: k,
    Module: m
}
}

ValidateGenesis

The ValidateGenesis(data GenesisState) method is called to verify that the provided genesisState is correct. It should perform validity checks on each of the parameters listed in GenesisState. See an example from the auth module:
package types

import (
    
	"encoding/json"
    "fmt"
    "sort"

	proto "github.com/cosmos/gogoproto/proto"
    "github.com/cosmos/cosmos-sdk/codec"
    "github.com/cosmos/cosmos-sdk/codec/types"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/types/module"
)

var _ types.UnpackInterfacesMessage = GenesisState{
}

/ RandomGenesisAccountsFn defines the function required to generate custom account types
type RandomGenesisAccountsFn func(simState *module.SimulationState)

GenesisAccounts

/ NewGenesisState - Create a new genesis state
func NewGenesisState(params Params, accounts GenesisAccounts) *GenesisState {
    genAccounts, err := PackAccounts(accounts)
    if err != nil {
    panic(err)
}

return &GenesisState{
    Params:   params,
    Accounts: genAccounts,
}
}

/ UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (g GenesisState)

UnpackInterfaces(unpacker types.AnyUnpacker)

error {
    for _, any := range g.Accounts {
    var account GenesisAccount
    err := unpacker.UnpackAny(any, &account)
    if err != nil {
    return err
}
	
}

return nil
}

/ DefaultGenesisState - Return a default genesis state
func DefaultGenesisState() *GenesisState {
    return NewGenesisState(DefaultParams(), GenesisAccounts{
})
}

/ GetGenesisStateFromAppState returns x/auth GenesisState given raw application
/ genesis state.
func GetGenesisStateFromAppState(cdc codec.Codec, appState map[string]json.RawMessage)

GenesisState {
    var genesisState GenesisState
    if appState[ModuleName] != nil {
    cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState)
}

return genesisState
}

/ ValidateGenesis performs basic validation of auth genesis data returning an
/ error for any failed validation criteria.
func ValidateGenesis(data GenesisState)

error {
    if err := data.Params.Validate(); err != nil {
    return err
}

genAccs, err := UnpackAccounts(data.Accounts)
    if err != nil {
    return err
}

return ValidateGenAccounts(genAccs)
}

/ SanitizeGenesisAccounts sorts accounts and coin sets.
func SanitizeGenesisAccounts(genAccs GenesisAccounts)

GenesisAccounts {
	/ Make sure there aren't any duplicated account numbers by fixing the duplicates with the lowest unused values.
	/ seenAccNum = easy lookup for used account numbers.
    seenAccNum := map[uint64]bool{
}
	/ dupAccNum = a map of account number to accounts with duplicate account numbers (excluding the 1st one seen).
    dupAccNum := map[uint64]GenesisAccounts{
}
    for _, acc := range genAccs {
    num := acc.GetAccountNumber()
    if !seenAccNum[num] {
    seenAccNum[num] = true
}

else {
    dupAccNum[num] = append(dupAccNum[num], acc)
}
	
}

	/ dupAccNums a sorted list of the account numbers with duplicates.
	var dupAccNums []uint64
    for num := range dupAccNum {
    dupAccNums = append(dupAccNums, num)
}

sort.Slice(dupAccNums, func(i, j int)

bool {
    return dupAccNums[i] < dupAccNums[j]
})

	/ Change the account number of the duplicated ones to the first unused value.
    globalNum := uint64(0)
    for _, dupNum := range dupAccNums {
    accs := dupAccNum[dupNum]
    for _, acc := range accs {
    for seenAccNum[globalNum] {
    globalNum++
}
    if err := acc.SetAccountNumber(globalNum); err != nil {
    panic(err)
}

seenAccNum[globalNum] = true
}
	
}

	/ Then sort them all by account number.
	sort.Slice(genAccs, func(i, j int)

bool {
    return genAccs[i].GetAccountNumber() < genAccs[j].GetAccountNumber()
})

return genAccs
}

/ ValidateGenAccounts validates an array of GenesisAccounts and checks for duplicates
func ValidateGenAccounts(accounts GenesisAccounts)

error {
    addrMap := make(map[string]bool, len(accounts))
    for _, acc := range accounts {
		/ check for duplicated accounts
    addrStr := acc.GetAddress().String()
    if _, ok := addrMap[addrStr]; ok {
    return fmt.Errorf("duplicate account found in genesis state; address: %s", addrStr)
}

addrMap[addrStr] = true

		/ check account specific validation
    if err := acc.Validate(); err != nil {
    return fmt.Errorf("invalid account found in genesis state; address: %s, error: %s", addrStr, err.Error())
}
	
}

return nil
}

/ GenesisAccountIterator implements genesis account iteration.
type GenesisAccountIterator struct{
}

/ IterateGenesisAccounts iterates over all the genesis accounts found in
/ appGenesis and invokes a callback on each genesis account. If any call
/ returns true, iteration stops.
func (GenesisAccountIterator)

IterateGenesisAccounts(
	cdc codec.Codec, appGenesis map[string]json.RawMessage, cb func(sdk.AccountI) (stop bool),
) {
    for _, genAcc := range GetGenesisStateFromAppState(cdc, appGenesis).Accounts {
    acc, ok := genAcc.GetCachedValue().(sdk.AccountI)
    if !ok {
    panic("expected account")
}
    if cb(acc) {
    break
}
	
}
}

/ PackAccounts converts GenesisAccounts to Any slice
func PackAccounts(accounts GenesisAccounts) ([]*types.Any, error) {
    accountsAny := make([]*types.Any, len(accounts))
    for i, acc := range accounts {
    msg, ok := acc.(proto.Message)
    if !ok {
    return nil, fmt.Errorf("cannot proto marshal %T", acc)
}

any, err := types.NewAnyWithValue(msg)
    if err != nil {
    return nil, err
}

accountsAny[i] = any
}

return accountsAny, nil
}

/ UnpackAccounts converts Any slice to GenesisAccounts
func UnpackAccounts(accountsAny []*types.Any) (GenesisAccounts, error) {
    accounts := make(GenesisAccounts, len(accountsAny))
    for i, any := range accountsAny {
    acc, ok := any.GetCachedValue().(GenesisAccount)
    if !ok {
    return nil, fmt.Errorf("expected genesis account")
}

accounts[i] = acc
}

return accounts, nil
}

Other Genesis Methods

Other than the methods related directly to GenesisState, module developers are expected to implement two other methods as part of the AppModuleGenesis interface (only if the module needs to initialize a subset of state in genesis). These methods are InitGenesis and ExportGenesis.

InitGenesis

The InitGenesis method is executed during InitChain when the application is first started. Given a GenesisState, it initializes the subset of the state managed by the module by using the module’s keeper setter function on each parameter within the GenesisState. The module manager of the application is responsible for calling the InitGenesis method of each of the application’s modules in order. This order is set by the application developer via the manager’s SetOrderGenesisMethod, which is called in the application’s constructor function. See an example of InitGenesis from the auth module:
package keeper

import (
    
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/x/auth/types"
)

/ InitGenesis - Init store state from genesis data
/
/ CONTRACT: old coins from the FeeCollectionKeeper need to be transferred through
/ a genesis port script to the new fee collector account
func (ak AccountKeeper)

InitGenesis(ctx sdk.Context, data types.GenesisState) {
    if err := ak.Params.Set(ctx, data.Params); err != nil {
    panic(err)
}

accounts, err := types.UnpackAccounts(data.Accounts)
    if err != nil {
    panic(err)
}

accounts = types.SanitizeGenesisAccounts(accounts)

	/ Set the accounts and make sure the global account number matches the largest account number (even if zero).
	var lastAccNum *uint64
    for _, acc := range accounts {
    accNum := acc.GetAccountNumber()
    for lastAccNum == nil || *lastAccNum < accNum {
    n := ak.NextAccountNumber(ctx)

lastAccNum = &n
}

ak.SetAccount(ctx, acc)
}

ak.GetModuleAccount(ctx, types.FeeCollectorName)
}

/ ExportGenesis returns a GenesisState for a given context and keeper
func (ak AccountKeeper)

ExportGenesis(ctx sdk.Context) *types.GenesisState {
    params := ak.GetParams(ctx)

var genAccounts types.GenesisAccounts
	ak.IterateAccounts(ctx, func(account sdk.AccountI)

bool {
    genAccount := account.(types.GenesisAccount)

genAccounts = append(genAccounts, genAccount)

return false
})

return types.NewGenesisState(params, genAccounts)
}

ExportGenesis

The ExportGenesis method is executed whenever an export of the state is made. It takes the latest known version of the subset of the state managed by the module and creates a new GenesisState out of it. This is mainly used when the chain needs to be upgraded via a hard fork. See an example of ExportGenesis from the auth module.
package keeper

import (
    
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/x/auth/types"
)

/ InitGenesis - Init store state from genesis data
/
/ CONTRACT: old coins from the FeeCollectionKeeper need to be transferred through
/ a genesis port script to the new fee collector account
func (ak AccountKeeper)

InitGenesis(ctx sdk.Context, data types.GenesisState) {
    if err := ak.Params.Set(ctx, data.Params); err != nil {
    panic(err)
}

accounts, err := types.UnpackAccounts(data.Accounts)
    if err != nil {
    panic(err)
}

accounts = types.SanitizeGenesisAccounts(accounts)

	/ Set the accounts and make sure the global account number matches the largest account number (even if zero).
	var lastAccNum *uint64
    for _, acc := range accounts {
    accNum := acc.GetAccountNumber()
    for lastAccNum == nil || *lastAccNum < accNum {
    n := ak.NextAccountNumber(ctx)

lastAccNum = &n
}

ak.SetAccount(ctx, acc)
}

ak.GetModuleAccount(ctx, types.FeeCollectorName)
}

/ ExportGenesis returns a GenesisState for a given context and keeper
func (ak AccountKeeper)

ExportGenesis(ctx sdk.Context) *types.GenesisState {
    params := ak.GetParams(ctx)

var genAccounts types.GenesisAccounts
	ak.IterateAccounts(ctx, func(account sdk.AccountI)

bool {
    genAccount := account.(types.GenesisAccount)

genAccounts = append(genAccounts, genAccount)

return false
})

return types.NewGenesisState(params, genAccounts)
}

GenesisTxHandler

GenesisTxHandler is a way for modules to submit state transitions prior to the first block. This is used by x/genutil to submit the genesis transactions for the validators to be added to staking.
package genesis

/ TxHandler is an interface that modules can implement to provide genesis state transitions
type TxHandler interface {
    ExecuteGenesisTx([]byte)

error
}