docs/sdk: various updates

This commit is contained in:
Ethan Buchman 2018-06-16 22:56:53 -07:00
parent 671956c74c
commit 03f3b96085
6 changed files with 77 additions and 41 deletions

View File

@ -9,7 +9,7 @@ NOTE: This documentation is a work-in-progress!
- [Application Architecture](overview/apps.md) - Layers in the application architecture
- [Install](install.md) - Install the library and example applications
- [Core](core)
- [BaseApp](core/baseapp.md) - BaseApp is the base layer of the appication
- [BaseApp](core/baseapp.md) - BaseApp is the base layer of the application
- [The MultiStore](core/multistore.md) - MultiStore is a rich Merkle database
- [Messages](core/messages.md) - Messages contain the content of a transaction
- [Handlers](core/handlers.md) - Handlers are the workhorse of the app!

View File

@ -1,5 +1,4 @@
## Accounts and x/auth
# Accounts
### auth.Account

View File

@ -0,0 +1,36 @@
# Amino
The SDK is flexible about serialization - application developers can use any
serialization scheme to encode transactions and state. However, the SDK provides
a native serialization format called
[Amino](https://github.com/tendermint/go-amino).
The goal of Amino is to improve over the latest version of Protocol Buffers,
`proto3`. To that end, Amino is compatible with the subset of `proto3` that
excludes the `oneof` keyword.
While `oneof` provides union types, Amino aims to provide interfaces.
The main difference being that with union types, you have to know all the types
up front. But anyone can implement an interface type whenever and however
they like.
To implement interface types, Amino allows any concrete implementation of an
interface to register a globally unique name that is carried along whenever the
type is serialized. This allows Amino to seamlessly deserialize into interface
types!
The primary use for Amino in the SDK is for messages that implement the
`Msg` interface. By registering each message with a distinct name, they are each
given a distinct Amino prefix, allowing them to be easily distinguished in
transactions.
Amino can also be used for persistent storage of interfaces.
To use Amino, simply create a codec, and then register types:
```
cdc := wire.NewCodec()
cdc.RegisterConcrete(MsgSend{}, "cosmos-sdk/Send", nil)
cdc.RegisterConcrete(MsgIssue{}, "cosmos-sdk/Issue", nil)
```

View File

@ -1,3 +1,4 @@
# Message Handling
## Context
@ -7,7 +8,7 @@ become ubiquitous in networking middleware and routing applications as a means
to easily propogate request context through handler functions.
The main information stored in the `Context` includes the application
MultiStore (see below), the last block header, and the transaction bytes.
MultiStore, the last block header, and the transaction bytes.
Effectively, the context contains all data that may be necessary for processing
a transaction.
@ -25,30 +26,27 @@ 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 (all referenced from the
root MultiStore), a particular handler only needs a particular kind of access
to a particular store (or two or more). Access to stores is managed using
capabilities keys and mappers. When a handler is initialized, it is passed a
key or mapper that gives it access to the relevant stores.
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
// File: cosmos-sdk/examples/basecoin/app/init_stores.go
app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL)
app.accountMapper = auth.NewAccountMapper(
app.capKeyMainStore, // target store
&types.AppAccount{}, // prototype
)
// File: cosmos-sdk/examples/basecoin/app/init_handlers.go
app.router.AddRoute("bank", bank.NewHandler(app.accountMapper))
// File: cosmos-sdk/x/bank/handler.go
// NOTE: Technically, NewHandler only needs a CoinMapper
func NewHandler(am sdk.AccountMapper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
cm := CoinMapper{am}
...
}
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!

View File

@ -1,7 +1,7 @@
# Messages
### Messages
Users can create messages containing arbitrary information by
Messages are the primary inputs to application state machines.
Developers can create messages containing arbitrary information by
implementing the `Msg` interface:
```go
@ -31,7 +31,7 @@ correspond to the messages handler, so there can be many messages with the same
type.
Messages must also specify how they are to be authenticated. The `GetSigners()`
method return a list of addresses that must sign the message, while the
method return a list of SDK addresses that must sign the message, while the
`GetSignBytes()` method returns the bytes that must be signed for a signature
to be valid.
@ -45,11 +45,13 @@ begins.
For instance, the `Basecoin` message types are defined in `x/bank/tx.go`:
```go
// Send coins from many inputs to many outputs.
type MsgSend struct {
Inputs []Input `json:"inputs"`
Outputs []Output `json:"outputs"`
}
// Issue new coins to many outputs.
type MsgIssue struct {
Banker sdk.Address `json:"banker"`
Outputs []Output `json:"outputs"`

View File

@ -1,6 +1,4 @@
## Storage
## MultiStore
# MultiStore
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
@ -34,23 +32,26 @@ barKey := sdk.NewKVStoreKey("bar")
catKey := sdk.NewKVStoreKey("cat")
```
Stores can either specify there own database, or share a primary one.
In this example, `foo` and `bar` will share a primary database, while `cat` will
Stores are mounted directly on the BaseApp.
They can either specify their own database, or share the primary one already
passed to the BaseApp.
In this example, `foo` and `bar` will share the primary database, while `cat` will
specify its own:
```
mainDB, catDB := dbm.NewMemDB(), dbm.NewMemDB()
ms := NewCommitMultiStore(mainDB)
ms.MountStoreWithDB(fooKey, sdk.StoreTypeIAVL, nil)
ms.MountStoreWithDB(barKey, sdk.StoreTypeIAVL, nil)
ms.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB)
catDB := dbm.NewMemDB()
app.MountStore(fooKey, sdk.StoreTypeIAVL)
app.MountStore(barKey, sdk.StoreTypeIAVL)
app.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB)
```
## Accessing Stores
In the Cosmos-SDK, the only way to access a store is with a capability-key.
Only modules given explicit access to the capability-key will
be able to access the corresponding store.
be able to access the corresponding store. Access to the MultiStore is mediated
through the `Context`.
## Notes