more app1/app2 cleanup
This commit is contained in:
parent
e7081040d0
commit
778b102a52
|
@ -229,41 +229,6 @@ us to easily lookup transactions that pertain to particular accounts or actions.
|
|||
|
||||
Let's define our handler for App1:
|
||||
|
||||
```go
|
||||
func NewApp1Handler(keyAcc *sdk.KVStoreKey) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
switch msg := msg.(type) {
|
||||
case MsgSend:
|
||||
return handleMsgSend(ctx, keyAcc, msg)
|
||||
default:
|
||||
errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name()
|
||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We have only a single message type, so just one message-specific function to define, `handleMsgSend`.
|
||||
|
||||
Note this handler has unrestricted access to the store specified by the capability key `keyAcc`,
|
||||
so it must define what to store and how to encode it. Later, we'll introduce
|
||||
higher-level abstractions so Handlers are restricted in what they can do.
|
||||
For this first example, we use a simple account that is JSON encoded:
|
||||
|
||||
```go
|
||||
type appAccount struct {
|
||||
Coins sdk.Coins `json:"coins"`
|
||||
}
|
||||
```
|
||||
|
||||
Coins is a useful type provided by the SDK for multi-asset accounts.
|
||||
We could just use an integer here for a single coin type, but
|
||||
it's worth [getting to know
|
||||
Coins](https://godoc.org/github.com/cosmos/cosmos-sdk/types#Coins).
|
||||
|
||||
|
||||
Now we're ready to handle the MsgSend:
|
||||
|
||||
```go
|
||||
// Handle MsgSend.
|
||||
// NOTE: msg.From, msg.To, and msg.Amount were already validated
|
||||
|
@ -290,10 +255,26 @@ func handleMsgSend(ctx sdk.Context, key *sdk.KVStoreKey, msg MsgSend) sdk.Result
|
|||
}
|
||||
```
|
||||
|
||||
The handler is straight forward. We first load the KVStore from the context using the granted capability key.
|
||||
Then we make two state transitions: one for the sender, one for the receiver.
|
||||
Each one involves JSON unmarshalling the account bytes from the store, mutating
|
||||
the `Coins`, and JSON marshalling back into the store:
|
||||
We have only a single message type, so just one message-specific function to define, `handleMsgSend`.
|
||||
|
||||
Note this handler has unrestricted access to the store specified by the capability key `keyAcc`,
|
||||
so it must define what to store and how to encode it. Later, we'll introduce
|
||||
higher-level abstractions so Handlers are restricted in what they can do.
|
||||
For this first example, we use a simple account that is JSON encoded:
|
||||
|
||||
```go
|
||||
type appAccount struct {
|
||||
Coins sdk.Coins `json:"coins"`
|
||||
}
|
||||
```
|
||||
|
||||
Coins is a useful type provided by the SDK for multi-asset accounts.
|
||||
We could just use an integer here for a single coin type, but
|
||||
it's worth [getting to know
|
||||
Coins](https://godoc.org/github.com/cosmos/cosmos-sdk/types#Coins).
|
||||
|
||||
|
||||
Now we're ready to handle the two parts of the MsgSend:
|
||||
|
||||
```go
|
||||
func handleFrom(store sdk.KVStore, from sdk.Address, amt sdk.Coins) sdk.Result {
|
||||
|
@ -367,6 +348,11 @@ func handleTo(store sdk.KVStore, to sdk.Address, amt sdk.Coins) sdk.Result {
|
|||
}
|
||||
```
|
||||
|
||||
The handler is straight forward. We first load the KVStore from the context using the granted capability key.
|
||||
Then we make two state transitions: one for the sender, one for the receiver.
|
||||
Each one involves JSON unmarshalling the account bytes from the store, mutating
|
||||
the `Coins`, and JSON marshalling back into the store.
|
||||
|
||||
And that's that!
|
||||
|
||||
## Tx
|
||||
|
|
|
@ -74,24 +74,36 @@ func handleMsgIssue(keyIssue *sdk.KVStoreKey, keyAcc *sdk.KVStoreKey) sdk.Handle
|
|||
func handleIssuer(store sdk.KVStore, issuer sdk.Address, coin sdk.Coin) sdk.Result {
|
||||
// the issuer address is stored directly under the coin denomination
|
||||
denom := []byte(coin.Denom)
|
||||
issuerAddress := store.Get(denom)
|
||||
if issuerAddress == nil {
|
||||
infoBytes := store.Get(denom)
|
||||
if infoBytes == nil {
|
||||
return sdk.ErrInvalidCoins(fmt.Sprintf("Unknown coin type %s", coin.Denom)).Result()
|
||||
}
|
||||
|
||||
var coinInfo coinInfo
|
||||
err := json.Unmarshal(infoBytes, &coinInfo)
|
||||
if err != nil {
|
||||
return sdk.ErrInternal("Error when deserializing coinInfo").Result()
|
||||
}
|
||||
|
||||
// Msg Issuer is not authorized to issue these coins
|
||||
if !bytes.Equal(issuerAddress, issuer) {
|
||||
if !bytes.Equal(coinInfo.Issuer, issuer) {
|
||||
return sdk.ErrUnauthorized(fmt.Sprintf("Msg Issuer cannot issue tokens: %s", coin.Denom)).Result()
|
||||
}
|
||||
|
||||
return sdk.Result{}
|
||||
}
|
||||
|
||||
// coinInfo stores meta data about a coin
|
||||
type coinInfo struct {
|
||||
Issuer sdk.Address `json:"issuer"`
|
||||
}
|
||||
```
|
||||
|
||||
Note we're just storing the issuer address for each coin directly under the
|
||||
coin's denomination in the issuer store. We could of course use a struct with more
|
||||
fields, like the current supply of coins in existence, and the maximum supply
|
||||
allowed to be issued.
|
||||
Note we've introduced the `coinInfo` type to store the issuer address for each coin.
|
||||
We JSON serialize this type and store it directly under the denomination in the
|
||||
issuer store. We could of course add more fields and logic around this,
|
||||
like including the current supply of coins in existence, and enforcing a maximum supply,
|
||||
but that's left as an excercise for the reader :).
|
||||
|
||||
## Amino
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ func (msg MsgIssue) Tags() sdk.Tags {
|
|||
//------------------------------------------------------------------
|
||||
// Handler for the message
|
||||
|
||||
// Handle MsgIssue
|
||||
// Handle MsgIssue.
|
||||
func handleMsgIssue(keyIssue *sdk.KVStoreKey, keyAcc *sdk.KVStoreKey) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
issueMsg, ok := msg.(MsgIssue)
|
||||
|
@ -149,19 +149,30 @@ func handleMsgIssue(keyIssue *sdk.KVStoreKey, keyAcc *sdk.KVStoreKey) sdk.Handle
|
|||
func handleIssuer(store sdk.KVStore, issuer sdk.Address, coin sdk.Coin) sdk.Result {
|
||||
// the issuer address is stored directly under the coin denomination
|
||||
denom := []byte(coin.Denom)
|
||||
issuerAddress := store.Get(denom)
|
||||
if issuerAddress == nil {
|
||||
infoBytes := store.Get(denom)
|
||||
if infoBytes == nil {
|
||||
return sdk.ErrInvalidCoins(fmt.Sprintf("Unknown coin type %s", coin.Denom)).Result()
|
||||
}
|
||||
|
||||
var coinInfo coinInfo
|
||||
err := json.Unmarshal(infoBytes, &coinInfo)
|
||||
if err != nil {
|
||||
return sdk.ErrInternal("Error when deserializing coinInfo").Result()
|
||||
}
|
||||
|
||||
// Msg Issuer is not authorized to issue these coins
|
||||
if !bytes.Equal(issuerAddress, issuer) {
|
||||
if !bytes.Equal(coinInfo.Issuer, issuer) {
|
||||
return sdk.ErrUnauthorized(fmt.Sprintf("Msg Issuer cannot issue tokens: %s", coin.Denom)).Result()
|
||||
}
|
||||
|
||||
return sdk.Result{}
|
||||
}
|
||||
|
||||
// coinInfo stores meta data about a coin
|
||||
type coinInfo struct {
|
||||
Issuer sdk.Address `json:"issuer"`
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Tx
|
||||
|
||||
|
|
Loading…
Reference in New Issue