docs/sdk: various updates
This commit is contained in:
parent
671956c74c
commit
03f3b96085
|
@ -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!
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
## Accounts and x/auth
|
||||
# Accounts
|
||||
|
||||
### auth.Account
|
||||
|
||||
|
|
|
@ -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)
|
||||
```
|
|
@ -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 {
|
||||
func newFooHandler(key sdk.StoreKey) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
cm := CoinMapper{am}
|
||||
...
|
||||
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!
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue