basecoin upgrade without CLI
This commit is contained in:
parent
6dec9353be
commit
131130b7a4
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
|
@ -53,8 +54,10 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp {
|
|||
|
||||
// add handlers
|
||||
coinKeeper := bank.NewCoinKeeper(app.accountMapper)
|
||||
coolMapper := cool.NewMapper(app.capKeyMainStore)
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(coinKeeper)).
|
||||
AddRoute("cool", cool.NewHandler(coinKeeper, coolMapper)).
|
||||
AddRoute("sketchy", sketchy.NewHandler())
|
||||
|
||||
// initialize BaseApp
|
||||
|
@ -73,39 +76,34 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp {
|
|||
}
|
||||
|
||||
// custom tx codec
|
||||
// TODO: use new go-wire
|
||||
func MakeCodec() *wire.Codec {
|
||||
|
||||
// XXX: Using old wire for now :)
|
||||
const (
|
||||
msgTypeSend = 0x1
|
||||
msgTypeIssue = 0x2
|
||||
)
|
||||
const msgTypeSend = 0x1
|
||||
const msgTypeIssue = 0x2
|
||||
var _ = oldwire.RegisterInterface(
|
||||
struct{ sdk.Msg }{},
|
||||
oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend},
|
||||
oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue},
|
||||
)
|
||||
|
||||
const (
|
||||
accTypeApp = 0x1
|
||||
)
|
||||
const accTypeApp = 0x1
|
||||
var _ = oldwire.RegisterInterface(
|
||||
struct{ sdk.Account }{},
|
||||
oldwire.ConcreteType{&types.AppAccount{}, accTypeApp},
|
||||
)
|
||||
|
||||
cdc := wire.NewCodec()
|
||||
// TODO: use new go-wire
|
||||
|
||||
// cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
||||
// bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types.
|
||||
// crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types.
|
||||
return cdc
|
||||
|
||||
}
|
||||
|
||||
// custom logic for transaction decoding
|
||||
func (app *BasecoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) {
|
||||
var tx = sdk.StdTx{}
|
||||
|
||||
// StdTx.Msg is an interface. The concrete types
|
||||
// are registered by MakeTxCodec in bank.RegisterWire.
|
||||
err := app.cdc.UnmarshalBinary(txBytes, &tx)
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package cool
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
)
|
||||
|
||||
// This is just an example to demonstrate a functional custom module
|
||||
// with full feature set functionality.
|
||||
//
|
||||
// /$$$$$$$ /$$$$$$ /$$$$$$ /$$
|
||||
// /$$_____/ /$$__ $$ /$$__ $$| $$
|
||||
//| $$ | $$ \ $$| $$ \ $$| $$
|
||||
//| $$ | $$ | $$| $$ | $$| $$
|
||||
//| $$$$$$$| $$$$$$/| $$$$$$/| $$$$$$$
|
||||
// \_______/ \______/ \______/ |______/
|
||||
|
||||
// Handle all "coolmodule" type objects
|
||||
func NewHandler(ck bank.CoinKeeper, cm Mapper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
switch msg := msg.(type) {
|
||||
case SetWhatCoolMsg:
|
||||
return handleSetWhatCoolMsg(ctx, cm, msg)
|
||||
case WhatCoolMsg:
|
||||
return handleWhatCoolMsg(ctx, ck, cm, msg)
|
||||
default:
|
||||
errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name())
|
||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle WhatCoolMsg This is the engine of your module
|
||||
func handleSetWhatCoolMsg(ctx sdk.Context, cm Mapper, msg SetWhatCoolMsg) sdk.Result {
|
||||
cm.SetWhatCool(ctx, msg.WhatCool)
|
||||
return sdk.Result{}
|
||||
}
|
||||
|
||||
// Handle WhatCoolMsg This is the engine of your module
|
||||
func handleWhatCoolMsg(ctx sdk.Context, ck bank.CoinKeeper, cm Mapper, msg WhatCoolMsg) sdk.Result {
|
||||
|
||||
whatsCool := cm.GetWhatCool(ctx)
|
||||
|
||||
if msg.CoolerThanCool == whatsCool {
|
||||
|
||||
bonusCoins := sdk.Coins{{whatsCool, 69}}
|
||||
_, err := ck.AddCoins(ctx, msg.Sender, bonusCoins)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
}
|
||||
|
||||
return sdk.Result{}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package cool
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// This Cool Mapper handlers sets/gets of custom variables for your module
|
||||
type Mapper struct {
|
||||
key sdk.StoreKey // The (unexposed) key used to access the store from the Context.
|
||||
}
|
||||
|
||||
func NewMapper(key sdk.StoreKey) Mapper {
|
||||
return Mapper{key}
|
||||
}
|
||||
|
||||
// Key to knowing whats cool
|
||||
var whatCoolKey = []byte("WhatsCoolKey")
|
||||
|
||||
// Implements sdk.AccountMapper.
|
||||
func (am Mapper) GetWhatCool(ctx sdk.Context) string {
|
||||
store := ctx.KVStore(am.key)
|
||||
bz := store.Get(whatCoolKey)
|
||||
return string(bz)
|
||||
}
|
||||
|
||||
// Implements sdk.AccountMapper.
|
||||
func (am Mapper) SetWhatCool(ctx sdk.Context, whatscool string) {
|
||||
store := ctx.KVStore(am.key)
|
||||
store.Set(whatCoolKey, []byte(whatscool))
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package cool
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// A really cool msg type, these fields are can be entirely arbitrary and
|
||||
// custom to your message
|
||||
type SetWhatCoolMsg struct {
|
||||
Sender sdk.Address
|
||||
WhatCool string
|
||||
}
|
||||
|
||||
// New cool message
|
||||
func NewSetWhatCoolMsg(sender sdk.Address, whatcool string) SetWhatCoolMsg {
|
||||
return SetWhatCoolMsg{
|
||||
Sender: sender,
|
||||
WhatCool: whatcool,
|
||||
}
|
||||
}
|
||||
|
||||
// enforce the msg type at compile time
|
||||
var _ sdk.Msg = SetWhatCoolMsg{}
|
||||
|
||||
// nolint
|
||||
func (msg SetWhatCoolMsg) Type() string { return "cool" }
|
||||
func (msg SetWhatCoolMsg) Get(key interface{}) (value interface{}) { return nil }
|
||||
func (msg SetWhatCoolMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
|
||||
func (msg SetWhatCoolMsg) String() string {
|
||||
return fmt.Sprintf("SetWhatCoolMsg{Sender: %v, WhatCool: %v}", msg.Sender, msg.WhatCool)
|
||||
}
|
||||
|
||||
// Validate Basic is used to quickly disqualify obviously invalid messages quickly
|
||||
func (msg SetWhatCoolMsg) ValidateBasic() sdk.Error {
|
||||
if len(msg.Sender) == 0 {
|
||||
return sdk.ErrUnrecognizedAddress(msg.Sender).Trace("")
|
||||
}
|
||||
if strings.Contains(msg.WhatCool, "hot") {
|
||||
return sdk.ErrUnauthorized("").Trace("hot is not cool")
|
||||
}
|
||||
if strings.Contains(msg.WhatCool, "warm") {
|
||||
return sdk.ErrUnauthorized("").Trace("warm is not very cool")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the bytes for the message signer to sign on
|
||||
func (msg SetWhatCoolMsg) GetSignBytes() []byte {
|
||||
b, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// A really cool msg type, these fields are can be entirely arbitrary and
|
||||
// custom to your message
|
||||
type WhatCoolMsg struct {
|
||||
Sender sdk.Address
|
||||
CoolerThanCool string
|
||||
}
|
||||
|
||||
// New cool message
|
||||
func NewWhatCoolMsg(sender sdk.Address, coolerthancool string) WhatCoolMsg {
|
||||
return WhatCoolMsg{
|
||||
Sender: sender,
|
||||
CoolerThanCool: coolerthancool,
|
||||
}
|
||||
}
|
||||
|
||||
// enforce the msg type at compile time
|
||||
var _ sdk.Msg = WhatCoolMsg{}
|
||||
|
||||
// nolint
|
||||
func (msg WhatCoolMsg) Type() string { return "cool" }
|
||||
func (msg WhatCoolMsg) Get(key interface{}) (value interface{}) { return nil }
|
||||
func (msg WhatCoolMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
|
||||
func (msg WhatCoolMsg) String() string {
|
||||
return fmt.Sprintf("WhatCoolMsg{Sender: %v, CoolerThanCool: %v}", msg.Sender, msg.CoolerThanCool)
|
||||
}
|
||||
|
||||
// Validate Basic is used to quickly disqualify obviously invalid messages quickly
|
||||
func (msg WhatCoolMsg) ValidateBasic() sdk.Error {
|
||||
if len(msg.Sender) == 0 {
|
||||
return sdk.ErrUnrecognizedAddress(msg.Sender).Trace("")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the bytes for the message signer to sign on
|
||||
func (msg WhatCoolMsg) GetSignBytes() []byte {
|
||||
b, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package coolmodule
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
)
|
||||
|
||||
// This is just an example to demonstrate a functional custom module
|
||||
// with full feature set functionality.
|
||||
//
|
||||
// /$$$$$$$ /$$$$$$ /$$$$$$ /$$
|
||||
// /$$_____/ /$$__ $$ /$$__ $$| $$
|
||||
//| $$ | $$ \ $$| $$ \ $$| $$
|
||||
//| $$ | $$ | $$| $$ | $$| $$
|
||||
//| $$$$$$$| $$$$$$/| $$$$$$/| $$$$$$$
|
||||
// \_______/ \______/ \______/ |______/
|
||||
|
||||
// Handle all "coolmodule" type objects
|
||||
func NewHandler(ck bank.CoinKeeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
switch msg := msg.(type) {
|
||||
case CoolMsg:
|
||||
return handleCoolMsg(ctx, ck, msg)
|
||||
case CoolerThanCoolMsg:
|
||||
return handleMeltMsg(ctx, ck, msg)
|
||||
default:
|
||||
errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name()
|
||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle CoolMsg This is the engine of your module
|
||||
func handleCoolMsg(ctx sdk.Context, ck CoinKeeper, msg CoolMsg) sdk.Result {
|
||||
|
||||
if msg.coolerthancool == "icecold" {
|
||||
|
||||
bonusCoins := sdk.Coins{{"icecold", 69}}
|
||||
_, err := ck.AddCoins(ctx, msg.Address, bonusCoins)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
}
|
||||
|
||||
return sdk.Result{}
|
||||
}
|
||||
|
||||
// Handle CoolMsg This is the engine of your module
|
||||
func handleMeltMsg(ctx sdk.Context, ck CoinKeeper, msg CoolMsg) sdk.Result {
|
||||
|
||||
// checks for existence should already have occured
|
||||
if strings.Prefix(msg.what, "ice") {
|
||||
return bank.ErrInvalidInput("only frozen coins can use the blow dryer")
|
||||
}
|
||||
|
||||
bonusCoins := sdk.Coins{{"icecold", 69}}
|
||||
_, err := ck.SubtractCoins(ctx, msg.Address, bonusCoins)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
return sdk.Result{}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package coolmodule
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// A really cool msg type, these fields are can be entirely arbitrary and
|
||||
// custom to your message
|
||||
type CoolMsg struct {
|
||||
Sender sdk.Address
|
||||
Coolerthancool string
|
||||
}
|
||||
|
||||
// New cool message
|
||||
func NewCoolMsg(sender sdk.Address, coolerthancool string) CoolMsg {
|
||||
return CoolMsg{
|
||||
Sender: sender,
|
||||
Coolerthancool: coolerthancool,
|
||||
}
|
||||
}
|
||||
|
||||
// enforce the msg type at compile time
|
||||
var _ CoolMsg = sdk.Msg
|
||||
|
||||
// nolint
|
||||
func (msg CoolMsg) Type() string { return "cool" }
|
||||
func (msg CoolMsg) Get(key interface{}) (value interface{}) { return nil }
|
||||
func (msg CoolMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
|
||||
func (msg CoolMsg) String() string { return fmt.Sprintf("CoolMsg{%v}", msg) }
|
||||
|
||||
// Validate Basic is used to quickly disqualify obviously invalid messages quickly
|
||||
func (msg CoolMsg) ValidateBasic() sdk.Error {
|
||||
if msg.Signer.Empty() {
|
||||
return ErrNoOutputs().Trace("")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the bytes for the message signer to sign on
|
||||
func (msg CoolMsg) GetSignBytes() []byte {
|
||||
b, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// A really cool msg type, these fields are can be entirely arbitrary and
|
||||
// custom to your message
|
||||
type BlowDryMsg struct {
|
||||
Sender sdk.Address
|
||||
What sdk.Coin
|
||||
}
|
||||
|
||||
// New cool message
|
||||
func NewBlowDryMsg(sender sdk.Address, what sdk.Coin) BlowDryMsg {
|
||||
return BlowDryMsg{
|
||||
Sender: sender,
|
||||
What: what,
|
||||
}
|
||||
}
|
||||
|
||||
// enforce the msg type at compile time
|
||||
var _ BlowDryMsg = sdk.Msg
|
||||
|
||||
// nolint
|
||||
func (msg BlowDryMsg) Type() string { return "cool" }
|
||||
func (msg BlowDryMsg) Get(key interface{}) (value interface{}) { return nil }
|
||||
func (msg BlowDryMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
|
||||
func (msg BlowDryMsg) String() string { return fmt.Sprintf("BlowDryMsg{%v}", msg) }
|
||||
|
||||
// Validate Basic is used to quickly disqualify obviously invalid messages quickly
|
||||
func (msg BlowDryMsg) ValidateBasic() sdk.Error {
|
||||
if msg.Signer.Empty() {
|
||||
return ErrNoOutputs().Trace("")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the bytes for the message signer to sign on
|
||||
func (msg BlowDryMsg) GetSignBytes() []byte {
|
||||
b, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
|
@ -15,7 +15,7 @@ type SendMsg struct {
|
|||
Outputs []Output `json:"outputs"`
|
||||
}
|
||||
|
||||
var _ SendMsg = (nil)(sdk.Msg)
|
||||
var _ sdk.Msg = SendMsg{}
|
||||
|
||||
// NewSendMsg - construct arbitrary multi-in, multi-out send msg.
|
||||
func NewSendMsg(in []Input, out []Output) SendMsg {
|
||||
|
|
Loading…
Reference in New Issue