func (app *BaseApp) setCheckState(header abci.Header) {
	ms := app.cms.CacheMultiStore()
	app.checkState = &state{
		ms:  ms,
		ctx: sdk.NewContext(ms, header, true, app.logger).WithMinGasPrices(app.minGasPrices),
	}
}
setCheckState sets checkState with the cached multistore and
the context wrapping it.
It is called by InitChain() and Commit()
package baseapp
import (
	"errors"
	"fmt"
	"os"
	"reflect"
	"runtime/debug"
	"strings"
	"github.com/gogo/protobuf/proto"
	abci "github.com/tendermint/tendermint/abci/types"
	"github.com/tendermint/tendermint/crypto/tmhash"
	"github.com/tendermint/tendermint/libs/log"
	dbm "github.com/tendermint/tm-db"
	"github.com/Dipper-Labs/Dipper-Protocol/app/protocol"
	"github.com/Dipper-Labs/Dipper-Protocol/codec"
	"github.com/Dipper-Labs/Dipper-Protocol/store"
	sdk "github.com/Dipper-Labs/Dipper-Protocol/types"
	sdkerrors "github.com/Dipper-Labs/Dipper-Protocol/types/errors"
)
type runTxMode uint8
const (
	runTxModeCheck    runTxMode = iota  
	runTxModeReCheck                    
	runTxModeSimulate                   
	runTxModeDeliver                    
)
var (
	_ abci.Application = (*BaseApp)(nil)
	mainConsensusParamsKey = []byte("consensus_params")
)
type BaseApp struct {
	name   string  
	logger log.Logger
	db     dbm.DB                
	cms    sdk.CommitMultiStore  
	txDecoder sdk.TxDecoder  
	Engine    *protocol.ProtocolEngine
	baseKey *sdk.KVStoreKey  
	addrPeerFilter sdk.PeerFilter  
	idPeerFilter   sdk.PeerFilter  
	fauxMerkleMode bool            
	checkState   *state  
	deliverState *state  
	voteInfos []abci.VoteInfo  
	consensusParams *abci.ConsensusParams
	minGasPrices sdk.DecCoins
	sealed bool
	haltHeight uint64
	appVersion string
	PostEndBlocker sdk.PostEndBlockHandler
}
func NewBaseApp(name string, logger log.Logger, db dbm.DB, options ...func(*BaseApp)) *BaseApp {  
	app := &BaseApp{
		logger:         logger,
		name:           name,
		db:             db,
		cms:            store.NewCommitMultiStore(db),
		fauxMerkleMode: false,
	}
	for _, option := range options {
		option(app)
	}
	return app
}
func (app *BaseApp) WithEngine(engine *protocol.ProtocolEngine) *BaseApp {
	app.Engine = engine
	return app
}
func (app *BaseApp) Name() string {
	return app.name
}
func (app *BaseApp) AppVersion() string {
	return app.appVersion
}
func (app *BaseApp) Logger() log.Logger {
	return app.logger
}
func (app *BaseApp) MountStores(keys ...sdk.StoreKey) {
	for _, key := range keys {
		switch key.(type) {
		case *sdk.KVStoreKey:
			if !app.fauxMerkleMode {
				app.MountStore(key, sdk.StoreTypeIAVL)
			} else {
				app.MountStore(key, sdk.StoreTypeDB)
			}
		case *sdk.TransientStoreKey:
			app.MountStore(key, sdk.StoreTypeTransient)
		default:
			panic("Unrecognized store key type " + reflect.TypeOf(key).Name())
		}
	}
}
func (app *BaseApp) MountKVStores(keys map[string]*sdk.KVStoreKey) {
	for _, key := range keys {
		if !app.fauxMerkleMode {
			app.MountStore(key, sdk.StoreTypeIAVL)
		} else {
			app.MountStore(key, sdk.StoreTypeDB)
		}
	}
}
func (app *BaseApp) MountTransientStores(keys map[string]*sdk.TransientStoreKey) {
	for _, key := range keys {
		app.MountStore(key, sdk.StoreTypeTransient)
	}
}
func (app *BaseApp) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) {
	app.cms.MountStoreWithDB(key, typ, db)
}
func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) {
	app.cms.MountStoreWithDB(key, typ, nil)
}
func (app *BaseApp) LoadLatestVersion(baseKey *sdk.KVStoreKey) error {
	err := app.cms.LoadLatestVersion()
	if err != nil {
		return err
	}
	return app.initFromMainStore(baseKey)
}
func (app *BaseApp) LoadVersion(version int64, baseKey *sdk.KVStoreKey) error {
	err := app.cms.LoadVersion(version)
	if err != nil {
		return err
	}
	return app.initFromMainStore(baseKey)
}
func (app *BaseApp) LastCommitID() sdk.CommitID {
	return app.cms.LastCommitID()
}
func (app *BaseApp) LastBlockHeight() int64 {
	return app.cms.LastCommitID().Version
}
func (app *BaseApp) initFromMainStore(baseKey *sdk.KVStoreKey) error {
	mainStore := app.cms.GetKVStore(baseKey)
	if mainStore == nil {
		return errors.New("baseapp expects MultiStore with 'main' KVStore")
	}
	if app.baseKey != nil {
		panic("app.baseKey expected to be nil; duplicate init?")
	}
	app.baseKey = baseKey
	consensusParamsBz := mainStore.Get(mainConsensusParamsKey)
	if consensusParamsBz != nil {
		var consensusParams = &abci.ConsensusParams{}
		err := proto.Unmarshal(consensusParamsBz, consensusParams)
		if err != nil {
			panic(err)
		}
		app.setConsensusParams(consensusParams)
	}
	app.setCheckState(abci.Header{})
	app.Seal()
	return nil
}
func (app *BaseApp) SetProtocolEngine(pe *protocol.ProtocolEngine) {
	if app.sealed {
		panic("SetProtocolEngine() on sealed BaseApp")
	}
	app.Engine = pe
}
func (app *BaseApp) setMinGasPrices(gasPrices sdk.DecCoins) {
	fmt.Fprintf(os.Stdout, "minimus gas prices: %s\n", gasPrices.String())
	app.minGasPrices = gasPrices
}
func (app *BaseApp) setHaltHeight(height uint64) {
	app.haltHeight = height
}
func (app *BaseApp) Seal() { app.sealed = true }
func (app *BaseApp) IsSealed() bool { return app.sealed }