more app1/app2 cleanup

This commit is contained in:
Ethan Buchman 2018-06-28 20:08:38 -04:00
parent e7081040d0
commit 778b102a52
3 changed files with 59 additions and 50 deletions

View File

@ -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

View File

@ -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

View File

@ -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