some cleanup, remove old files
This commit is contained in:
parent
b335d3bb70
commit
0c5e3fdc74
|
@ -94,7 +94,7 @@ func (msg MsgSend) ValidateBasic() sdk.Error {
|
|||
}
|
||||
```
|
||||
|
||||
# KVStore
|
||||
## KVStore
|
||||
|
||||
The basic persistence layer for an SDK application is the KVStore:
|
||||
|
||||
|
@ -140,7 +140,7 @@ like Ethereum's radix trie.
|
|||
As we'll soon see, apps have many distinct KVStores, each with a different name and for a different concern.
|
||||
Access to a store is mediated by *object-capability keys*, which must be granted to a handler during application startup.
|
||||
|
||||
# Handlers
|
||||
## Handlers
|
||||
|
||||
Now that we have a message type and a store interface, we can define our state transition function using a handler:
|
||||
|
||||
|
@ -150,11 +150,12 @@ type Handler func(ctx Context, msg Msg) Result
|
|||
```
|
||||
|
||||
Along with the message, the Handler takes environmental information (a `Context`), and returns a `Result`.
|
||||
All information necessary for processing a message should be available in the context.
|
||||
|
||||
Where is the KVStore in all of this? Access to the KVStore in a message handler is restricted by the Context via object-capability keys.
|
||||
Only handlers which were given explict access to a store's key will be able to access that store during message processsing.
|
||||
|
||||
## Context
|
||||
### Context
|
||||
|
||||
The SDK uses a `Context` to propogate common information across functions.
|
||||
Most importantly, the `Context` restricts access to KVStores based on object-capability keys.
|
||||
|
@ -181,7 +182,7 @@ The Context also contains the [block header](TODO), which includes the latest ti
|
|||
|
||||
See the [Context API docs](TODO) for more details.
|
||||
|
||||
## Result
|
||||
### Result
|
||||
|
||||
Handler takes a Context and Msg and returns a Result.
|
||||
Result is motivated by the corresponding [ABCI result](TODO). It contains return values, error information, logs, and meta data about the transaction:
|
||||
|
@ -219,7 +220,7 @@ We'll talk more about these fields later in the tutorial. For now, note that a
|
|||
failure. The `Tags` can contain meta data about the transaction that will allow
|
||||
us to easily lookup transactions that pertain to particular accounts or actions.
|
||||
|
||||
## Handler
|
||||
### Handler
|
||||
|
||||
Let's define our handler for App1:
|
||||
|
||||
|
@ -455,8 +456,11 @@ func NewApp1(logger log.Logger, db dbm.DB) *bapp.BaseApp {
|
|||
Every app will have such a function that defines the setup of the app.
|
||||
It will typically be contained in an `app.go` file.
|
||||
We'll talk about how to connect this app object with the CLI, a REST API,
|
||||
the logger, and the filesystem later in the tutorial. For now, note that this is where we grant handlers access to stores.
|
||||
Here, we have only one store and one handler, and the handler is granted access by giving it the capability key.
|
||||
the logger, and the filesystem later in the tutorial. For now, note that this is where we
|
||||
register handlers for messages and grant them access to stores.
|
||||
|
||||
Here, we have only a single Msg type, `bank`, a single store for accounts, and a single handler.
|
||||
The handler is granted access to the store by giving it the capability key.
|
||||
In future apps, we'll have multiple stores and handlers, and not every handler will get access to every store.
|
||||
|
||||
After setting the transaction decoder and the message handling routes, the final
|
||||
|
|
|
@ -108,6 +108,21 @@ constructor):
|
|||
accountMapper := auth.NewAccountMapper(cdc, keyAccount, &auth.BaseAccount{})
|
||||
```
|
||||
|
||||
Then we can get, modify, and set accounts. For instance, we could double the
|
||||
amount of coins in an account:
|
||||
|
||||
```go
|
||||
acc := GetAccount(ctx, addr)`
|
||||
acc.SetCoins(acc.Coins.Plus(acc.Coins))
|
||||
acc.SetAccount(ctx, addr)
|
||||
```
|
||||
|
||||
Note that the `AccountMapper` takes a `Context` as the first argument, and will
|
||||
load the KVStore from there using the capability key it was granted on creation.
|
||||
|
||||
Also note that you must explicitly call `SetAccount` after mutating an account
|
||||
for the change to persist!
|
||||
|
||||
See the [AccountMapper API docs](TODO) for more information.
|
||||
|
||||
## StdTx
|
||||
|
@ -242,6 +257,27 @@ the StdSignature once. From that point on, it will be stored in the account.
|
|||
The fee is paid by the first address returned by msg.GetSigners() for the first `Msg`.
|
||||
The convenience function `FeePayer(tx Tx) sdk.Address` is provided to return this.
|
||||
|
||||
## CoinKeeper
|
||||
|
||||
Updating accounts is made easier by using the `Keeper` struct in the `x/bank` module.
|
||||
|
||||
Example Initialization:
|
||||
|
||||
```go
|
||||
// File: examples/basecoin/app/app.go
|
||||
app.coinKeeper = bank.NewKeeper(app.accountMapper)
|
||||
```
|
||||
|
||||
Example Usage:
|
||||
|
||||
```go
|
||||
// Finds account with addr in accountmapper
|
||||
// Adds coins to account's coin array
|
||||
// Sets updated account in accountmapper
|
||||
app.coinKeeper.AddCoins(ctx, addr, coins)
|
||||
```
|
||||
|
||||
|
||||
## App3
|
||||
|
||||
Putting it all together, we get:
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
# Handlers
|
||||
|
||||
A handler takes a context and a message and returns a result. All
|
||||
information necessary for processing a message should be available in the
|
||||
context.
|
||||
|
||||
While the context holds the entire application state (ie. the
|
||||
MultiStore), handlers are restricted in what they can do based on the
|
||||
capabilities they were given when the application was set up.
|
||||
|
||||
For instance, suppose we have a `newFooHandler`:
|
||||
|
||||
```go
|
||||
func newFooHandler(key sdk.StoreKey) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
store := ctx.KVStore(key)
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This handler can only access one store based on whichever key its given.
|
||||
So when we register the handler for the `foo` message type, we make sure
|
||||
to give it the `fooKey`:
|
||||
|
||||
```
|
||||
app.Router().AddRoute("foo", newFooHandler(fooKey))
|
||||
```
|
||||
|
||||
Now it can only access the `foo` store, but not the `bar` or `cat` stores!
|
||||
|
|
@ -10,8 +10,7 @@ the Basecoin application, with each implementation showcasing a new component of
|
|||
the SDK:
|
||||
|
||||
- App1 - The Basics - Messages, Stores, Handlers, BaseApp
|
||||
- App2 - Amino - Unmarshalling into interfaces
|
||||
- App3 - Authentication - Accounts and Transactions, Signatures and Replay protection
|
||||
- App4 - Access Control - Keepers selective expose access to stores
|
||||
- App5 - Validator Set Changes - Change the Tendermint validator set
|
||||
- App6 - Basecoin - Bringing it all together
|
||||
- App2 - Transactions - Amino and AnteHandler
|
||||
- App3 - Modules - `x/auth` and `x/bank`
|
||||
- App4 - Validator Set Changes - Change the Tendermint validator set
|
||||
- App5 - Basecoin - Bringing it all together
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
# MultiStore
|
||||
|
||||
TODO: reconcile this
|
||||
TODO: reconcile this with everything ... would be nice to have this explanation
|
||||
somewhere but where does it belong ? So far we've already showed how to use it
|
||||
all by creating KVStore keys and calling app.MountStoresIAVL !
|
||||
|
||||
|
||||
The Cosmos-SDK provides a special Merkle database called a `MultiStore` to be used for all application
|
||||
storage. The MultiStore consists of multiple Stores that must be mounted to the
|
||||
|
|
Loading…
Reference in New Issue