package app import ( "encoding/json" abci "github.com/tendermint/abci/types" oldwire "github.com/tendermint/go-wire" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" bam "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool" "github.com/cosmos/cosmos-sdk/examples/basecoin/x/sketchy" ) const ( appName = "BasecoinApp" ) // Extended ABCI application type BasecoinApp struct { *bam.BaseApp cdc *wire.Codec // keys to access the substores capKeyMainStore *sdk.KVStoreKey capKeyIBCStore *sdk.KVStoreKey capKeyStakingStore *sdk.KVStoreKey // Manage getting and setting accounts accountMapper sdk.AccountMapper } func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // create your application object var app = &BasecoinApp{ BaseApp: bam.NewBaseApp(appName, logger, db), cdc: MakeCodec(), capKeyMainStore: sdk.NewKVStoreKey("main"), capKeyIBCStore: sdk.NewKVStoreKey("ibc"), capKeyStakingStore: sdk.NewKVStoreKey("staking"), } // define the accountMapper app.accountMapper = auth.NewAccountMapperSealed( app.capKeyMainStore, // target store &types.AppAccount{}, // prototype ) // add handlers coinKeeper := bank.NewCoinKeeper(app.accountMapper) coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper) ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) stakingMapper := staking.NewMapper(app.capKeyStakingStore) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). AddRoute("cool", coolKeeper.Handler). AddRoute("sketchy", sketchy.NewHandler()). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("staking", staking.NewHandler(stakingMapper, coinKeeper)) // initialize BaseApp app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { cmn.Exit(err.Error()) } return app } // custom tx codec // TODO: use new go-wire func MakeCodec() *wire.Codec { const msgTypeSend = 0x1 const msgTypeIssue = 0x2 const msgTypeQuiz = 0x3 const msgTypeSetTrend = 0x4 const msgTypeIBCTransferMsg = 0x5 const msgTypeIBCReceiveMsg = 0x6 const msgTypeBondMsg = 0x7 const msgTypeUnbondMsg = 0x8 var _ = oldwire.RegisterInterface( struct{ sdk.Msg }{}, oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, oldwire.ConcreteType{cool.QuizMsg{}, msgTypeQuiz}, oldwire.ConcreteType{cool.SetTrendMsg{}, msgTypeSetTrend}, oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg}, oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, oldwire.ConcreteType{staking.BondMsg{}, msgTypeBondMsg}, oldwire.ConcreteType{staking.UnbondMsg{}, msgTypeUnbondMsg}, ) const accTypeApp = 0x1 var _ = oldwire.RegisterInterface( struct{ sdk.Account }{}, oldwire.ConcreteType{&types.AppAccount{}, accTypeApp}, ) cdc := wire.NewCodec() // cdc.RegisterInterface((*sdk.Msg)(nil), nil) // bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types. // crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types. // ibc.RegisterWire(cdc) // Register ibc.[IBCTransferMsg, IBCReceiveMsg] types. return cdc } // custom logic for transaction decoding func (app *BasecoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { var tx = sdk.StdTx{} if len(txBytes) == 0 { return nil, sdk.ErrTxDecode("txBytes are empty") } // StdTx.Msg is an interface. The concrete types // are registered by MakeTxCodec in bank.RegisterWire. err := app.cdc.UnmarshalBinary(txBytes, &tx) if err != nil { return nil, sdk.ErrTxDecode("").TraceCause(err, "") } return tx, nil } // custom logic for basecoin initialization func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { stateJSON := req.AppStateBytes genesisState := new(types.GenesisState) err := json.Unmarshal(stateJSON, genesisState) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") } for _, gacc := range genesisState.Accounts { acc, err := gacc.ToAppAccount() if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") } app.accountMapper.SetAccount(ctx, acc) } return abci.ResponseInitChain{} }