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
|
- [Application Architecture](overview/apps.md) - Layers in the application architecture
|
||||||
- [Install](install.md) - Install the library and example applications
|
- [Install](install.md) - Install the library and example applications
|
||||||
- [Core](core)
|
- [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
|
- [The MultiStore](core/multistore.md) - MultiStore is a rich Merkle database
|
||||||
- [Messages](core/messages.md) - Messages contain the content of a transaction
|
- [Messages](core/messages.md) - Messages contain the content of a transaction
|
||||||
- [Handlers](core/handlers.md) - Handlers are the workhorse of the app!
|
- [Handlers](core/handlers.md) - Handlers are the workhorse of the app!
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
# Accounts
|
||||||
## Accounts and x/auth
|
|
||||||
|
|
||||||
### auth.Account
|
### 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
|
## Context
|
||||||
|
|
||||||
|
@ -7,7 +8,7 @@ become ubiquitous in networking middleware and routing applications as a means
|
||||||
to easily propogate request context through handler functions.
|
to easily propogate request context through handler functions.
|
||||||
|
|
||||||
The main information stored in the `Context` includes the application
|
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
|
Effectively, the context contains all data that may be necessary for processing
|
||||||
a transaction.
|
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
|
information necessary for processing a message should be available in the
|
||||||
context.
|
context.
|
||||||
|
|
||||||
While the context holds the entire application state (all referenced from the
|
While the context holds the entire application state (ie. the
|
||||||
root MultiStore), a particular handler only needs a particular kind of access
|
MultiStore), handlers are restricted in what they can do based on the
|
||||||
to a particular store (or two or more). Access to stores is managed using
|
capabilities they were given when the application was set up.
|
||||||
capabilities keys and mappers. When a handler is initialized, it is passed a
|
|
||||||
key or mapper that gives it access to the relevant stores.
|
For instance, suppose we have a `newFooHandler`:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// File: cosmos-sdk/examples/basecoin/app/init_stores.go
|
func newFooHandler(key sdk.StoreKey) sdk.Handler {
|
||||||
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 {
|
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
|
Messages are the primary inputs to application state machines.
|
||||||
|
Developers can create messages containing arbitrary information by
|
||||||
Users can create messages containing arbitrary information by
|
|
||||||
implementing the `Msg` interface:
|
implementing the `Msg` interface:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
@ -31,7 +31,7 @@ correspond to the messages handler, so there can be many messages with the same
|
||||||
type.
|
type.
|
||||||
|
|
||||||
Messages must also specify how they are to be authenticated. The `GetSigners()`
|
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
|
`GetSignBytes()` method returns the bytes that must be signed for a signature
|
||||||
to be valid.
|
to be valid.
|
||||||
|
|
||||||
|
@ -45,11 +45,13 @@ begins.
|
||||||
For instance, the `Basecoin` message types are defined in `x/bank/tx.go`:
|
For instance, the `Basecoin` message types are defined in `x/bank/tx.go`:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
// Send coins from many inputs to many outputs.
|
||||||
type MsgSend struct {
|
type MsgSend struct {
|
||||||
Inputs []Input `json:"inputs"`
|
Inputs []Input `json:"inputs"`
|
||||||
Outputs []Output `json:"outputs"`
|
Outputs []Output `json:"outputs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue new coins to many outputs.
|
||||||
type MsgIssue struct {
|
type MsgIssue struct {
|
||||||
Banker sdk.Address `json:"banker"`
|
Banker sdk.Address `json:"banker"`
|
||||||
Outputs []Output `json:"outputs"`
|
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
|
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
|
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")
|
catKey := sdk.NewKVStoreKey("cat")
|
||||||
```
|
```
|
||||||
|
|
||||||
Stores can either specify there own database, or share a primary one.
|
Stores are mounted directly on the BaseApp.
|
||||||
In this example, `foo` and `bar` will share a primary database, while `cat` will
|
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:
|
specify its own:
|
||||||
|
|
||||||
```
|
```
|
||||||
mainDB, catDB := dbm.NewMemDB(), dbm.NewMemDB()
|
catDB := dbm.NewMemDB()
|
||||||
ms := NewCommitMultiStore(mainDB)
|
app.MountStore(fooKey, sdk.StoreTypeIAVL)
|
||||||
ms.MountStoreWithDB(fooKey, sdk.StoreTypeIAVL, nil)
|
app.MountStore(barKey, sdk.StoreTypeIAVL)
|
||||||
ms.MountStoreWithDB(barKey, sdk.StoreTypeIAVL, nil)
|
app.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB)
|
||||||
ms.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Accessing Stores
|
## Accessing Stores
|
||||||
|
|
||||||
In the Cosmos-SDK, the only way to access a store is with a capability-key.
|
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
|
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
|
## Notes
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue