Merge pull request #239 from zramsay/build-sdk-app
docs: cleanups and consolidation.
This commit is contained in:
commit
c9d2fa5dbf
43
README.md
43
README.md
|
@ -1,6 +1,6 @@
|
|||
# Cosmos SDK
|
||||
|
||||
![banner](cosmos-sdk-image.png)
|
||||
![banner](docs/graphics/cosmos-sdk-image.png)
|
||||
|
||||
[![version](https://img.shields.io/github/tag/cosmos/cosmos-sdk.svg)](https://github.com/cosmos/cosmos-sdk/releases/latest)
|
||||
[![API Reference](https://godoc.org/github.com/cosmos/cosmos-sdk?status.svg
|
||||
|
@ -13,11 +13,20 @@ Branch | Tests | Coverage | Report Card
|
|||
develop | [![CircleCI](https://circleci.com/gh/cosmos/cosmos-sdk/tree/develop.svg?style=shield)](https://circleci.com/gh/cosmos/cosmos-sdk/tree/develop) | [![codecov](https://codecov.io/gh/cosmos/cosmos-sdk/branch/develop/graph/badge.svg)](https://codecov.io/gh/cosmos/cosmos-sdk) | [![Go Report Card](https://goreportcard.com/badge/github.com/cosmos/cosmos-sdk/tree/develop)](https://goreportcard.com/report/github.com/cosmos/cosmos-sdk/tree/develop)
|
||||
master | [![CircleCI](https://circleci.com/gh/cosmos/cosmos-sdk/tree/master.svg?style=shield)](https://circleci.com/gh/cosmos/cosmos-sdk/tree/master) | [![codecov](https://codecov.io/gh/cosmos/cosmos-sdk/branch/master/graph/badge.svg)](https://codecov.io/gh/cosmos/cosmos-sdk) | [![Go Report Card](https://goreportcard.com/badge/github.com/cosmos/cosmos-sdk/tree/master)](https://goreportcard.com/report/github.com/cosmos/cosmos-sdk/tree/master)
|
||||
|
||||
The Cosmos SDK is an [ABCI application](https://github.com/tendermint/abci) designed to be used with the [Tendermint consensus engine](https://tendermint.com/) to form a Proof-of-Stake cryptocurrency. It also provides a general purpose framework
|
||||
The Cosmos SDK is the middleware platform which the [Cosmos Hub](https://cosmos.network) is constructed from. The Hub is a blockchain (or, internet of blockchains) in which the Atom supply resides. The Atoms supply is defined at genesis and can change based on the rules of the Hub.
|
||||
|
||||
Under the hood, the Cosmos SDK is an [ABCI application](https://github.com/tendermint/abci) designed to be used with the [Tendermint consensus engine](https://tendermint.com/) to form a Proof-of-Stake cryptocurrency. It also provides a general purpose framework
|
||||
for extending the feature-set of the cryptocurrency by implementing plugins.
|
||||
|
||||
Within this repository, the `basecoin` app serves as a reference implementation for how we build ABCI applications in Go, and is the framework in which we implement the [Cosmos Hub](https://cosmos.network). **It's easy to use, and doesn't require any forking** - just implement your plugin, import the libraries, and away
|
||||
you go with a full-stack blockchain and command line tool for transacting.
|
||||
This SDK affords you all the tools you need to rapidly develop
|
||||
robust blockchains and blockchain applications which are interoperable with The
|
||||
Cosmos Hub. It is a blockchain development 'starter-pack' of common blockchain
|
||||
modules while not enforcing their use thus giving maximum flexibility for
|
||||
application customization. For example, does your app require fees, how do you
|
||||
want to log messages, do you enable IBC, do you even have a cryptocurrency? In
|
||||
this way, the Cosmos SDK is the **Rails of cryptocurrencies**.
|
||||
|
||||
Within this repository, the `basecoin` app serves as a reference implementation for how we build ABCI applications in Go, and is the framework in which we implement the [Cosmos Hub](https://cosmos.network). **It's easy to use, and doesn't require any forking** - just implement your plugin, import the libraries, and away you go with a full-stack blockchain and command line tool for transacting.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
@ -40,3 +49,29 @@ See the [install guide](/docs/guide/install.md) for more details.
|
|||
* See [more examples](https://github.com/cosmos/cosmos-academy)
|
||||
|
||||
To deploy a testnet, see our [repository of deployment tools](https://github.com/tendermint/tools).
|
||||
|
||||
# Inspiration
|
||||
|
||||
The basic concept for this SDK comes from years of web development. A number of
|
||||
patterns have arisen in that realm of software which enable people to build remote
|
||||
servers with APIs remarkably quickly and with high stability. The
|
||||
[ABCI](https://github.com/tendermint/abci) application interface is similar to
|
||||
a web API (`DeliverTx` is like POST and `Query` is like GET while `SetOption` is like
|
||||
the admin playing with the config file). Here are some patterns that might be
|
||||
useful:
|
||||
|
||||
* MVC - separate data model (storage) from business logic (controllers)
|
||||
* Routers - easily direct each request to the appropriate controller
|
||||
* Middleware - a series of wrappers that provide global functionality (like
|
||||
authentication) to all controllers
|
||||
* Modules (gems, package, etc) - developers can write a self-contained package
|
||||
with a given set of functionality, which can be imported and reused in other
|
||||
apps
|
||||
|
||||
Also at play is the concept of different tables/schemas in databases, thus you can
|
||||
keep the different modules safely separated and avoid any accidental (or malicious)
|
||||
overwriting of data.
|
||||
|
||||
Not all of these can be compare one-to-one in the blockchain world, but they do
|
||||
provide inspiration for building orthogonal pieces that can easily be combined
|
||||
into various applications.
|
||||
|
|
|
@ -14,7 +14,7 @@ By default we will serve on `http://localhost:2024`. CORS will be disabled by d
|
|||
The MVP will allow us to move around money. This involves the
|
||||
following functions:
|
||||
|
||||
## Construct an unsigned tx
|
||||
## Construct an unsigned transaction
|
||||
|
||||
`POST /build/send`
|
||||
|
|
@ -6,23 +6,24 @@ provide a background and general understanding of the different words and
|
|||
concepts that are used. Other documents will explain in more detail how to
|
||||
combine these concepts to build a particular application.
|
||||
|
||||
## Transaction (tx)
|
||||
## Transaction
|
||||
|
||||
A transaction is a packet of binary data that contains all information to
|
||||
validate and perform an action on the blockchain. The only other data that it
|
||||
interacts with is the current state of the chain (key-value store), and
|
||||
it must have a deterministic action. The tx is the main piece of one request.
|
||||
it must have a deterministic action. The transaction is the main piece of one
|
||||
request.
|
||||
|
||||
We currently make heavy use of [go-wire](https://github.com/tendermint/go-wire)
|
||||
and [data](https://github.com/tendermint/go-wire/tree/master/data) to provide
|
||||
binary and json encodings and decodings for `struct` or interface` objects.
|
||||
Here, encoding and decoding operations are designed to operate with interfaces
|
||||
nested any amount times (like an onion!). There is one public `TxMapper`
|
||||
in the basecoin root package, and all modules can register their own transaction types there. This allows us to deserialize the entire tx in
|
||||
one location (even with types defined in other repos), to easily embed
|
||||
an arbitrary tx inside another without specifying the type, and provide
|
||||
an automatic json representation to provide to users (or apps) to
|
||||
inspect the chain.
|
||||
in the basecoin root package, and all modules can register their own transaction
|
||||
types there. This allows us to deserialize the entire transaction in one location
|
||||
(even with types defined in other repos), to easily embed an arbitrary transaction
|
||||
inside another without specifying the type, and provide an automatic json
|
||||
representation allowing for users (or apps) to inspect the chain.
|
||||
|
||||
Note how we can wrap any other transaction, add a fee level, and not worry
|
||||
about the encoding in our module any more?
|
||||
|
@ -40,13 +41,13 @@ type Fee struct {
|
|||
As a request passes through the system, it may pick up information such as the
|
||||
authorization it has received from another middleware, or the block height the
|
||||
request runs at. In order to carry this information between modules it is
|
||||
saved to the context. further, it all information must be deterministic from
|
||||
the context in which the request runs (based on the tx and the block it was
|
||||
included in) and can be used to validate the tx.
|
||||
saved to the context. Further, all information must be deterministic from
|
||||
the context in which the request runs (based on the transaction and the block
|
||||
it was included in) and can be used to validate the transaction.
|
||||
|
||||
## Data Store
|
||||
|
||||
To be able to provide proofs to Tendermint, we keep all data in one key-value
|
||||
In order to provide proofs to Tendermint, we keep all data in one key-value
|
||||
(kv) store which is indexed with a merkle tree. This allows for the easy
|
||||
generation of a root hash and proofs for queries without requiring complex
|
||||
logic inside each module. Standardization of this process also allows powerful
|
||||
|
@ -54,7 +55,7 @@ light-client tooling as any store data may be verified on the fly.
|
|||
|
||||
The largest limitation of the current implemenation of the kv-store is that
|
||||
interface that the application must use can only `Get` and `Set` single data
|
||||
points. This said, there are some data structures like queues and range
|
||||
points. That said, there are some data structures like queues and range
|
||||
queries that are available in `state` package. These provide higher-level
|
||||
functionality in a standard format, but have not yet been integrated into the
|
||||
kv-store interface.
|
||||
|
@ -64,7 +65,7 @@ kv-store interface.
|
|||
One of the main arguments for blockchain is security. So while we encourage
|
||||
the use of third-party modules, all developers must be vigilant against
|
||||
security holes. If you use the
|
||||
[stack](https://github.com/tendermint/basecoin/tree/unstable/stack)
|
||||
[stack](https://github.com/cosmos/cosmos-sdk/tree/master/stack)
|
||||
package, it will provide two different types of compartmentalization security.
|
||||
|
||||
The first is to limit the working kv-store space of each module. When
|
||||
|
@ -76,15 +77,15 @@ naming scheme can ever lead to a collision. Inside a module, we can
|
|||
write using any key value we desire without the possibility that we
|
||||
have modified data belonging to separate module.
|
||||
|
||||
The second is to add permissions to the transaction context. The tx context
|
||||
can specify that the tx has been signed by one or multiple specific
|
||||
The second is to add permissions to the transaction context. The transaction
|
||||
context can specify that the tx has been signed by one or multiple specific
|
||||
[actors](https://github.com/tendermint/basecoin/blob/unstable/context.go#L18).
|
||||
A tx will only be executed if the permission requirements have been fulfilled.
|
||||
For example the sender of funds must have signed, or 2 out of 3
|
||||
A transactions will only be executed if the permission requirements have been
|
||||
fulfilled. For example the sender of funds must have signed, or 2 out of 3
|
||||
multi-signature actors must have signed a joint account. To prevent the
|
||||
forgery of account signatures from unintended modules each permission
|
||||
is associated with the module that granted it (in this case
|
||||
[auth](https://github.com/tendermint/basecoin/tree/unstable/modules/auth)),
|
||||
[auth](https://github.com/cosmos/cosmos-sdk/tree/master/modules/auth)),
|
||||
and if a module tries to add a permission for another module, it will
|
||||
panic. There is also protection if a module creates a brand new fake
|
||||
context to trick the downstream modules. Each context enforces
|
||||
|
@ -124,10 +125,10 @@ interoperability, much like `http.Handler` does in golang web development.
|
|||
|
||||
Middleware is a series of processing steps that any request must travel through
|
||||
before (and after) executing the registered `Handler`. Some examples are a
|
||||
logger (that records the time before executing the tx, then outputs info -
|
||||
including duration - after the execution), of a signature checker (which
|
||||
unwraps the tx by one layer, verifies signatures, and adds the permissions to
|
||||
the Context before passing the request along).
|
||||
logger (that records the time before executing the transaction, then outputs
|
||||
info - including duration - after the execution), of a signature checker (which
|
||||
unwraps the transaction by one layer, verifies signatures, and adds the
|
||||
permissions to the Context before passing the request along).
|
||||
|
||||
In keeping with the standardization of `http.Handler` and inspired by the
|
||||
super minimal [negroni](https://github.com/urfave/negroni/blob/master/README.md)
|
||||
|
@ -154,31 +155,31 @@ self-sufficient. Common elements of a module are:
|
|||
* middleware (to handler any wrapper transactions)
|
||||
|
||||
To enable a module, you must add the appropriate middleware (if any) to the
|
||||
stack in `main.go` for the client application (Quark default:
|
||||
stack in `main.go` for the client application (default:
|
||||
`basecli/main.go`), as well as adding the handler (if any) to the dispatcher
|
||||
(Quark default: `app/app.go`). Once the stack is compiled into a `Handler`,
|
||||
then each tx is handled by the appropriate module.
|
||||
(default: `app/app.go`). Once the stack is compiled into a `Handler`,
|
||||
then each transaction is handled by the appropriate module.
|
||||
|
||||
## Dispatcher
|
||||
|
||||
We usually will want to have multiple modules working together, and need to
|
||||
make sure the correct transactions get to the correct module. So we have have
|
||||
`coin` sending money, `roles` creating multi-sig accounts, and `ibc` following
|
||||
other chains all working together without interference.
|
||||
make sure the correct transactions get to the correct module. So we have
|
||||
`coin` sending money, `roles` to create multi-sig accounts, and `ibc` for
|
||||
following other chains all working together without interference.
|
||||
|
||||
After the chain of middleware, we can register a `Dispatcher`, which also
|
||||
implements the `Handler` interface. We then register a list of modules with
|
||||
the dispatcher. Every module has a unique `Name()`, which is used for
|
||||
isolating its state space. We use this same name for routing tx. Each tx
|
||||
implementation must be registed with go-wire via `TxMapper`, so we just look
|
||||
at the registered name of this tx, which should be of the form
|
||||
`<module name>/xxx`. The dispatcher grabs the appropriate module name from
|
||||
the tx name and routes it if the module is present.
|
||||
isolating its state space. We use this same name for routing transactions.
|
||||
Each transaction implementation must be registed with go-wire via `TxMapper`,
|
||||
so we just look at the registered name of this transaction, which should be
|
||||
of the form `<module name>/xxx`. The dispatcher grabs the appropriate module
|
||||
name from the tx name and routes it if the module is present.
|
||||
|
||||
This all seems a bit of magic, but really just making use of the other magic
|
||||
(go-wire) that we are already using, rather than add another layer. The only
|
||||
thing you need to remember is to use the following pattern, then all the tx
|
||||
will be properly routed:
|
||||
This all seems like a bit of magic, but really we're just making use of go-wire
|
||||
magic that we are already using, rather than add another layer. For all the
|
||||
transactions to be properly routed, the only thing you need to remember is to
|
||||
use the following pattern:
|
||||
|
||||
```golang
|
||||
const (
|
||||
|
@ -192,13 +193,12 @@ const (
|
|||
But wait, there's more... since we have isolated all the modules from each
|
||||
other, we need to allow some way for them to interact in a controlled fashion.
|
||||
One example is the `fee` middleware, which wants to deduct coins from the
|
||||
calling account and can accomplished most easilty with the `coin` module.
|
||||
calling account and can be accomplished most easily with the `coin` module.
|
||||
|
||||
If we want to make a call from the middleware, this is relatively simple. The
|
||||
middleware already has a handle to the `next` Handler, which will execute the
|
||||
rest of the stack. It can simple create a new SendTx and pass it down the
|
||||
stack. If it returns success, then do the rest of the processing (and send the
|
||||
original tx down the stack), otherwise abort.
|
||||
To make a call from the middleware, we the `next` Handler, which will execute
|
||||
the rest of the stack. It can create a new SendTx and pass it down the
|
||||
stack. If it returns success, do the rest of the processing (and send the
|
||||
original transaction down the stack), otherwise abort.
|
||||
|
||||
However, if one `Handler` inside the `Dispatcher` wants to do this, it becomes
|
||||
more complex. The solution is that the `Dispatcher` accepts not a `Handler`,
|
||||
|
@ -209,17 +209,15 @@ and call `stack.WrapHandler(h)` to convert it to a `Dispatchable` that never
|
|||
uses the callback.
|
||||
|
||||
One example of this is the counter app, which can optionally accept a payment.
|
||||
If the tx contains a payment, it must create a SendTx and pass this to the
|
||||
dispatcher to deduct the amount from the proper account. Take a look at
|
||||
[counter
|
||||
plugin](https://github.com/tendermint/basecoin/blob/unstable/docs/guide/counter/plugins/counter/counter.go)
|
||||
for a better idea.
|
||||
If the transaction contains a payment, it must create a SendTx and pass this
|
||||
to the dispatcher to deduct the amount from the proper account. Take a look at
|
||||
[counter plugin](https://github.com/cosmos/cosmos-sdk/blob/master/docs/guide/counter/plugins/counter/counter.go)for a better idea.
|
||||
|
||||
## Permissions
|
||||
|
||||
IPC requires a more complex permissioning system to allow the modules to have
|
||||
limited access to each other. Also to allow more types of permissions than
|
||||
simple public key signatures. So, rather than just use an address to identify
|
||||
limited access to each other and also to allow more types of permissions than
|
||||
simple public key signatures. Rather than just use an address to identify
|
||||
who is performing an action, we can use a more complex structure:
|
||||
|
||||
```golang
|
||||
|
@ -235,28 +233,26 @@ or initiate any sort of transaction. It doesn't just have to be a pubkey on
|
|||
this chain, it could stem from another app (such as multi-sig account), or even
|
||||
another chain (via IBC)
|
||||
|
||||
`ChainID` is to be used for IBC, which is discussed below, but right now focus
|
||||
on `App` and `Address`. For a signature, the App is `auth`, and any modules
|
||||
can check to see if a specific public key address signed like this
|
||||
`ctx.HasPermission(auth.SigPerm(addr))`. However, we can also authorize a tx
|
||||
with `roles`, which handles multi-sig accounts, it checks if there were enough
|
||||
signatures by checking as above, then it can add the role permission like `ctx
|
||||
= ctx.WithPermissions(NewPerm(assume.Role))`
|
||||
`ChainID` is for IBC, discussed below. Let's focus on `App` and `Address`.
|
||||
For a signature, the App is `auth`, and any modules can check to see if a
|
||||
specific public key address signed like this `ctx.HasPermission(auth.SigPerm(addr))`.
|
||||
However, we can also authorize a tx with `roles`, which handles multi-sig accounts,
|
||||
it checks if there were enough signatures by checking as above, then it can add
|
||||
the role permission like `ctx= ctx.WithPermissions(NewPerm(assume.Role))`
|
||||
|
||||
In addition to permissioning, the Actors are addresses just like public key
|
||||
In addition to the permissions schema, the Actors are addresses just like public key
|
||||
addresses. So one can create a mulit-sig role, then send coin there, which can
|
||||
only be moved upon meeting the authorization requirements from that module.
|
||||
`coin` doesn't even know the existence of `roles` and one could build any other
|
||||
sort of module to provide permissions (like bind the outcome of an election to
|
||||
move coins or to modify the accounts on a role).
|
||||
|
||||
One idea (not implemented) is to provide scopes on the permissions. Right now,
|
||||
if I sign a tx to one module, it can pass it on to any other module over IPC
|
||||
with the same permissions. It could move coins, vote in an election, or
|
||||
anything else. Ideally, when signing, one could also specify the scope(s) that
|
||||
this signature authorizes. The [oauth
|
||||
protocol](https://api.slack.com/docs/oauth-scopes) also has to deal with a
|
||||
similar problem, and maybe could provide some inspiration.
|
||||
One idea - not yet implemented - is to provide scopes on the permissions.
|
||||
Currently, if I sign a transaction to one module, it can pass it on to any other
|
||||
module over IPC with the same permissions. It could move coins, vote in an election,
|
||||
or anything else. Ideally, when signing, one could also specify the scope(s) that
|
||||
this signature authorizes. The [oauth protocol](https://api.slack.com/docs/oauth-scopes)
|
||||
also has to deal with a similar problem, and maybe could provide some inspiration.
|
||||
|
||||
|
||||
## Replay Protection
|
||||
|
@ -290,11 +286,11 @@ with other sequence numbers.
|
|||
|
||||
By abstracting out the nonce module in the stack, entire series of transactions
|
||||
can occur without needing to verify the nonce for each member of the series. An
|
||||
common example is a stack which will send coins and charge a fee. Within Quark
|
||||
common example is a stack which will send coins and charge a fee. Within the SDK
|
||||
this can be achieved using separate modules in a stack, one to send the coins
|
||||
and the other to charge the fee, however both modules do not need to check the
|
||||
nonce. This can occur as a separate module earlier in the stack.
|
||||
|
||||
## IBC (Inter-Blockchain Communication)
|
||||
|
||||
Wow, this is a big topic. Also a WIP. Add more here...
|
||||
Stay tuned!
|
Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 243 KiB |
|
@ -320,7 +320,6 @@ To remove all the files created and refresh your environment (e.g., if starting
|
|||
```shelldown[end-of-tutorials]
|
||||
basecli reset_all
|
||||
rm -rf ~/.basecoin
|
||||
rm -rf ~/.basecoin
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
|
|
@ -126,11 +126,11 @@ them. Of course, we can also expose queries on our plugin:
|
|||
countercli query counter
|
||||
```
|
||||
|
||||
Tada! We can now see that our custom counter plugin tx went through. You
|
||||
should see a Counter value of 1 representing the number of valid transactions.
|
||||
If we send another transaction, and then query again, we will see the value
|
||||
increment. Note that we need the sequence number here to send the coins
|
||||
(it didn't increment when we just pinged the counter)
|
||||
Tada! We can now see that our custom counter plugin transactions went through.
|
||||
You should see a Counter value of 1 representing the number of valid
|
||||
transactions. If we send another transaction, and then query again, we will
|
||||
see the value increment. Note that we need the sequence number here to send the
|
||||
coins (it didn't increment when we just pinged the counter)
|
||||
|
||||
```shelldown[4]
|
||||
countercli tx counter --name cool --countfee=2mycoin --sequence=2 --valid
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client/commands/proxy"
|
||||
"github.com/cosmos/cosmos-sdk/client/commands/query"
|
||||
"github.com/cosmos/cosmos-sdk/client/commands/seeds"
|
||||
|
||||
txcmd "github.com/cosmos/cosmos-sdk/client/commands/txs"
|
||||
bcount "github.com/cosmos/cosmos-sdk/docs/guide/counter/cmd/countercli/commands"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/modules/auth/commands"
|
||||
|
@ -21,15 +22,16 @@ import (
|
|||
noncecmd "github.com/cosmos/cosmos-sdk/modules/nonce/commands"
|
||||
)
|
||||
|
||||
// BaseCli represents the base command when called without any subcommands
|
||||
var BaseCli = &cobra.Command{
|
||||
// CounterCli represents the base command when called without any subcommands
|
||||
var CounterCli = &cobra.Command{
|
||||
Use: "countercli",
|
||||
Short: "Light client for tendermint",
|
||||
Long: `Basecli is an version of tmcli including custom logic to
|
||||
present a nice (not raw hex) interface to the basecoin blockchain structure.
|
||||
Short: "Example app built using the Cosmos SDK",
|
||||
Long: `Countercli is a demo app that includes custom logic to
|
||||
present a formatted interface to a custom blockchain structure.
|
||||
|
||||
This is a useful tool and also serves to demonstrate how to configure
|
||||
the Cosmos SDK to work for any custom ABCI app, see:
|
||||
|
||||
This is a useful tool, but also serves to demonstrate how one can configure
|
||||
tmcli to work for any custom abci app.
|
||||
`,
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,14 @@ If you aren't used to compile go programs and just want the released
|
|||
version of the code, please head to our [downloads](https://tendermint.com/download)
|
||||
page to get a pre-compiled binary for your platform.
|
||||
|
||||
On a good day, basecoin can be installed like a normal Go program:
|
||||
Usually, Cosmos SDK can be installed like a normal Go program:
|
||||
|
||||
```
|
||||
go get -u github.com/tendermint/basecoin/cmd/...
|
||||
go get -u github.com/cosmos/cosmos-sdk/cmd/...
|
||||
```
|
||||
|
||||
In some cases, if that fails, or if another branch is required,
|
||||
we use `glide` for dependency management.
|
||||
If the dependencies have been updated with breaking changes,
|
||||
or if another branch is required, `glide` is used for dependency management.
|
||||
Thus, assuming you've already run `go get` or otherwise cloned the repo,
|
||||
the correct way to install is:
|
||||
|
||||
|
@ -30,4 +30,3 @@ If you need another branch, make sure to run `git checkout <branch>`
|
|||
before `make all`. And if you switch branches a lot, especially
|
||||
touching other tendermint repos, you may need to `make fresh` sometimes
|
||||
so glide doesn't get confused with all the branches and versions lying around.
|
||||
|
||||
|
|
|
@ -6,35 +6,35 @@ and match modular elements as desired. Along side, all modules are permissioned
|
|||
and sandboxed to isolate modules for greater application security.
|
||||
|
||||
For more explanation please see the [standard
|
||||
library](https://github.com/tendermint/basecoin/blob/unstable/docs/quark/stdlib.md)
|
||||
library](stdlib.md)
|
||||
and
|
||||
[glossary](https://github.com/tendermint/basecoin/blob/unstable/docs/quark/glossary.md)
|
||||
[glossary](glossary.md)
|
||||
documentation.
|
||||
|
||||
For a more interconnected schematics see these
|
||||
[framework](https://github.com/tendermint/basecoin/blob/unstable/docs/graphics/overview-framework.png)
|
||||
[framework](graphics/overview-framework.png)
|
||||
and
|
||||
[security](https://github.com/tendermint/basecoin/blob/unstable/docs/graphics/overview-security.png)
|
||||
[security](graphics/overview-security.png)
|
||||
overviews.
|
||||
|
||||
## Framework Overview
|
||||
|
||||
### Transaction (tx)
|
||||
### Transactions (tx)
|
||||
|
||||
Each tx passes through the middleware stack which can be defined uniquely by
|
||||
each application. From the multiple layers of tx, each middleware may strip
|
||||
off one level, like an onion. As so, the transaction must be constructed to
|
||||
mirror the execution stack, and each middleware should allow embedding an
|
||||
arbitrary tx for the next layer in the stack.
|
||||
Each transaction passes through the middleware stack which can be defined
|
||||
uniquely by each application. From the multiple layers of transaction, each
|
||||
middleware may strip off one level, like an onion. As such, the transaction
|
||||
must be constructed to mirror the execution stack, and each middleware module
|
||||
should allow an arbitrary transaction to be embedded for the next layer in
|
||||
the stack.
|
||||
|
||||
<img src="https://github.com/tendermint/basecoin/blob/unstable/docs/graphics/tx.png" width=250>
|
||||
<img src="graphics/tx.png" width=250>
|
||||
|
||||
### Execution Stack
|
||||
|
||||
Middleware components allow for code reusability and integrability. A standard
|
||||
set of middleware are provided and can be mix-and-matched with custom
|
||||
middleware. Some of the [standard
|
||||
library](https://github.com/tendermint/basecoin/blob/unstable/docs/quark/stdlib.md)
|
||||
middleware. Some of the [standard library](stdlib.md)
|
||||
middlewares provided in this package include:
|
||||
- Logging
|
||||
- Recovery
|
||||
|
@ -45,37 +45,37 @@ middlewares provided in this package include:
|
|||
- Roles
|
||||
- Inter-Blockchain-Communication (IBC)
|
||||
|
||||
As a part of stack execution the state space provided to each middleware is
|
||||
As a part of stack execution the state space provided to each middleware is
|
||||
isolated (see [Data Store](overview.md#data-store)). When executing the stack,
|
||||
state-recovery points (checkpoints) can be assigned for stack execution of
|
||||
`CheckTx` or `DeliverTx`. This means, that all state changes will be reverted
|
||||
to the checkpoint state on failure when either being run as a part of `CheckTx`
|
||||
state-recovery checkpoints can be assigned for stack execution of `CheckTx`
|
||||
or `DeliverTx`. This means, that all state changes will be reverted to the
|
||||
checkpoint state on failure when either being run as a part of `CheckTx`
|
||||
or `DeliverTx`. Example usage of the checkpoints is when we may want to deduct
|
||||
a fee even if the end business logic fails, under this situation we would add
|
||||
the DeliverTx Checkpoint to after the fee middleware but before the business
|
||||
a fee even if the end business logic fails; under this situation we would add
|
||||
the `DeliverTx` checkpoint after the fee middleware but before the business
|
||||
logic. This diagram displays a typical process flow through an execution stack.
|
||||
|
||||
<img src="https://github.com/tendermint/basecoin/blob/unstable/docs/graphics/middleware.png" width=500>
|
||||
<img src="graphics/middleware.png" width=500>
|
||||
|
||||
### Dispatcher
|
||||
|
||||
The dispatcher handler aims to allow for reusable business logic. As a
|
||||
transaction is passed to the end handler, the dispatcher routes the logic to
|
||||
the correct module. To use the dispatcher tool all transaction types must
|
||||
the correct module. To use the dispatcher tool, all transaction types must
|
||||
first be registered with the dispatcher. Once registered the middleware stack
|
||||
or any other handler can call the dispatcher to execute a transaction.
|
||||
Similarity to the execution stack, when executing a transaction the dispatcher
|
||||
Similarly to the execution stack, when executing a transaction the dispatcher
|
||||
isolates the state space available to the designated module (see [Data
|
||||
Store](overview.md#data-store)).
|
||||
|
||||
<img src="https://github.com/tendermint/basecoin/blob/unstable/docs/graphics/dispatcher.png" width=600>
|
||||
<img src="graphics/dispatcher.png" width=600>
|
||||
|
||||
## Security Overview
|
||||
|
||||
### Permission
|
||||
|
||||
Each application is run in a sandbox to isolate security risks. When
|
||||
interfacing between applications, if a one of those application is compromised
|
||||
interfacing between applications, if one of those applications is compromised
|
||||
the entire network should still be secure. This is achieved through actor
|
||||
permissioning whereby each chain, account, or application can provided a
|
||||
designated permission for the transaction context to perform a specific action.
|
||||
|
@ -83,7 +83,7 @@ designated permission for the transaction context to perform a specific action.
|
|||
Context is passed through the middleware and dispatcher, allowing one to add
|
||||
permissions on this app-space, and check current permissions.
|
||||
|
||||
<img src="https://github.com/tendermint/basecoin/blob/unstable/docs/graphics/permission.png" width=500>
|
||||
<img src="graphics/permission.png" width=500>
|
||||
|
||||
### Data Store
|
||||
|
||||
|
@ -93,13 +93,11 @@ is achieved through the use of unique prefix assigned to each module. From the
|
|||
module's perspective it is no different, the module need-not have regard for
|
||||
the prefix as it is assigned outside of the modules scope. For example, if a
|
||||
module named `foo` wanted to write to the store it could save records under the
|
||||
key `bar` however the dispatcher would register that record in the persistent
|
||||
key `bar`, however, the dispatcher would register that record in the persistent
|
||||
state under `foo/bar`. Next time the `foo` app was called that record would be
|
||||
accessible to it under the assigned key `bar`. This effectively makes app
|
||||
prefixing invisible to each module while preventing each module from affecting
|
||||
each other module. Under this model no two registered modules are permitted to
|
||||
have the same namespace.
|
||||
|
||||
<img src="https://github.com/tendermint/basecoin/blob/unstable/docs/graphics/datastore.png" width=500>
|
||||
|
||||
|
||||
<img src="graphics/datastore.png" width=500>
|
|
@ -1,54 +0,0 @@
|
|||
# Quark
|
||||
|
||||
Quarks are the fundamental building blocks of atoms through which DNA, life,
|
||||
and matter arise. Similarly this package is the core framework for constructing
|
||||
the atom tokens which will power [The Cosmos Network](https://cosmos.network/).
|
||||
|
||||
The Quark framework affords you all the tools you need to rapidly develop
|
||||
robust blockchains and blockchain applications which are interoperable with The
|
||||
Cosmos Hub. Quark is an abstraction of [Tendermint](https://tendermint.com/)
|
||||
which provides the core consensus engine for your blockchain. Beyond consensus,
|
||||
Quark provides a blockchain development 'starter-pack' of common blockchain
|
||||
modules while not enforcing their use thus giving maximum flexibility for
|
||||
application customization. For example, do you require fees, how do you
|
||||
want to log messages, do you enable IBC, do you even have a cryptocurrency?
|
||||
|
||||
Disclaimer: when power and flexibility meet, the result is also some level of
|
||||
complexity and a learning curve. Here is an introduction to the core concepts
|
||||
embedded in Quark.
|
||||
|
||||
## Inspiration
|
||||
|
||||
The basic concept came from years of web development. A number of patterns
|
||||
have arisen in that realm of software which enable people to build remote
|
||||
servers with APIs remarkably quickly and with high stability. The
|
||||
[ABCI](https://github.com/tendermint/abci) application interface is similar to
|
||||
a web API (DeliverTx is like POST and Query is like GET and `SetOption` is like
|
||||
the admin playing with the config file). Here are some patterns that might be
|
||||
useful:
|
||||
|
||||
* MVC - separate data model (storage) from business logic (controllers)
|
||||
* Routers - easily direct each request to the appropriate controller
|
||||
* Middleware - a series of wrappers that provide global functionality (like
|
||||
authentication) to all controllers
|
||||
* Modules (gems, package, ...) - developers can write a self-contained package
|
||||
with a given set of functionality, which can be imported and reused in other
|
||||
apps
|
||||
|
||||
Also, the idea of different tables/schemas in databases, so you can keep the
|
||||
different modules safely separated and avoid any accidental (or malicious)
|
||||
overwriting of data.
|
||||
|
||||
Not all of these can be pulled one-to-one in the blockchain world, but they do
|
||||
provide inspiration to provide orthogonal pieces that can easily be combined
|
||||
into various applications.
|
||||
|
||||
## Further reading
|
||||
|
||||
* [Quark overview](overview.md)
|
||||
* [Glossary of the terms](glossary.md)
|
||||
* [Standard modules](stdlib.md)
|
||||
* Guide to building a module
|
||||
* Demo of CLI tool
|
||||
* IBC in detail
|
||||
* Diagrams... Coming Soon!
|
|
@ -1,9 +1,9 @@
|
|||
# Standard Library
|
||||
|
||||
The Quark framework comes bundled with a number of standard modules that
|
||||
The Cosmos-SDK comes bundled with a number of standard modules that
|
||||
provide common functionality useful across a wide variety of applications.
|
||||
Example usage of the modules is also provided. It is recommended to investigate
|
||||
if desired functionality is already provided before developing new modules.
|
||||
See examples below. It is recommended to investigate if desired
|
||||
functionality is already provided before developing new modules.
|
||||
|
||||
## Basic Middleware
|
||||
|
||||
|
@ -22,18 +22,18 @@ them as errors, so they can be handled normally.
|
|||
|
||||
### Signatures
|
||||
|
||||
The first layer of the tx contains the signatures to authorize it. This is
|
||||
then verified by `modules.auth.Signatures`. All tx may have one or multiple
|
||||
signatures which are then processed and verified by this middleware and then
|
||||
passed down the stack.
|
||||
The first layer of the transaction contains the signatures to authorize it.
|
||||
This is then verified by `modules.auth.Signatures`. All transactions may
|
||||
have one or multiple signatures which are then processed and verified by this
|
||||
middleware and then passed down the stack.
|
||||
|
||||
### Chain
|
||||
|
||||
The next layer of a tx (in the standard stack) binds the tx to a specific chain
|
||||
with an optional expiration height. This keeps the tx from being replayed on
|
||||
a fork or other such chain, as well as a partially signed multi-sig being delayed
|
||||
months before being committed to the chain. This functionality is provided in
|
||||
`modules.base.Chain`
|
||||
The next layer of a transaction (in the standard stack) binds the transaction
|
||||
to a specific chain with a block height that has an optional expiration. This
|
||||
keeps the transactions from being replayed on a fork or other such chain, as
|
||||
well as a partially signed multi-sig being delayed months before being
|
||||
committed to the chain. This functionality is provided in `modules.base.Chain`
|
||||
|
||||
### Nonce
|
||||
|
||||
|
@ -44,22 +44,22 @@ protection cross-IBC and cross-plugins and also allows signing parties to not
|
|||
be bound to waiting for a particular transaction to be completed before being
|
||||
able to sign a separate transaction.
|
||||
|
||||
Rather than force each module to implement its own replay protection, a tx
|
||||
stack may contain a nonce wrap and the account it belongs to. The nonce must
|
||||
contain a signed sequence number which is incremented one higher than the last
|
||||
request or the request is rejected. This is implemented in
|
||||
`modules.nonce.ReplayCheck`
|
||||
Rather than force each module to implement its own replay protection, a
|
||||
transaction stack may contain a nonce wrap and the account it belongs to. The
|
||||
nonce must contain a signed sequence number which is incremented one higher
|
||||
than the last request or the request is rejected. This is implemented in
|
||||
`modules.nonce.ReplayCheck`.
|
||||
|
||||
If you're interested checkout this [design
|
||||
discussion](https://github.com/tendermint/basecoin/issues/160).
|
||||
discussion](https://github.com/cosmos/cosmos-sdk/issues/160).
|
||||
|
||||
### Fees
|
||||
|
||||
An optional feature, but useful on many chains, is charging transaction fees. A
|
||||
simple implementation of this is provided in `modules.fee.SimpleFeeMiddleware`.
|
||||
An optional - but useful - feature on many chains, is charging transaction fees.
|
||||
A simple implementation of this is provided in `modules.fee.SimpleFeeMiddleware`.
|
||||
A fee currency and minimum amount are defined in the constructor (eg. in code).
|
||||
If the minimum amount is 0, then the fee is optional. If it is above 0, then
|
||||
every tx with insufficient fee is rejected. This fee is deducted from the
|
||||
every transaction with insufficient fee is rejected. This fee is deducted from the
|
||||
payers account before executing any other transaction.
|
||||
|
||||
This module is dependent on the `coin` module.
|
||||
|
@ -82,7 +82,7 @@ requires some payment solution, like fees or trader.
|
|||
|
||||
### Roles
|
||||
|
||||
Roles encapsulates what are typically called N-of-M multi-signatures accounts
|
||||
Roles encapsulate what are typically called N-of-M multi-signatures accounts
|
||||
in the crypto world. However, I view this as a type of role or group, which can
|
||||
be the basis for building a permission system. For example, a set of people
|
||||
could be called registrars, which can authorize a new IBC chain, and need eg. 2
|
||||
|
@ -95,7 +95,7 @@ a role is planned in the near future.
|
|||
|
||||
### Inter-Blockchain Communication (IBC)
|
||||
|
||||
IBC, is the cornerstone of The Cosmos Network, and is built into the quark
|
||||
IBC, is the cornerstone of The Cosmos Network, and is built into the Cosmos-SDK
|
||||
framework as a basic primitive. To fully grasp these concepts requires
|
||||
a much longer explanation, but in short, the chain works as a light-client to
|
||||
another chain and maintains input and output queue to send packets with that
|
||||
|
@ -108,36 +108,21 @@ block), and this generally requires approval of an authorized registrar (which
|
|||
may be a multi-sig role). Updating a registered chain can be done by anyone,
|
||||
as the new header can be completely verified by the existing knowledge of the
|
||||
chain. Also, modules can initiate an outgoing IBC message to another chain
|
||||
by calling `CreatePacketTx` over IPC (inter-plugin communication) with a tx
|
||||
that belongs to their module. (This must be explicitly authorized by the
|
||||
same module, so only the eg. coin module can authorize a `SendTx` to another
|
||||
chain).
|
||||
by calling `CreatePacketTx` over IPC (inter-plugin communication) with a
|
||||
transaction that belongs to their module. (This must be explicitly authorized
|
||||
by the same module, so only the eg. coin module can authorize a `SendTx` to
|
||||
another chain).
|
||||
|
||||
`PostPacketTx` can post a tx that was created on another chain along with the
|
||||
merkle proof, which must match an already registered header. If this chain
|
||||
can verify the authenticity, it will accept the packet, along with all the
|
||||
permissions from the other chain, and execute it on this stack. This is the
|
||||
`PostPacketTx` can post a transaction that was created on another chain along
|
||||
with the merkle proof, which must match an already registered header. If this
|
||||
chain can verify the authenticity, it will accept the packet, along with all
|
||||
the permissions from the other chain, and execute it on this stack. This is the
|
||||
only way to get permissions that belong to another chain.
|
||||
|
||||
These various pieces can be combined in a relay, which polls for new packets
|
||||
on one chain, and then posts the packets along with the new headers on the
|
||||
other chain.
|
||||
|
||||
## Planned Apps
|
||||
|
||||
### Staking
|
||||
|
||||
Straight-forward PoS as used for cosmos.
|
||||
Based on [basecoin-stake](https://github.com/tendermint/basecoin-stake)
|
||||
|
||||
### Voting
|
||||
|
||||
Simple elections that can authorize other tx, like roles. A building block for
|
||||
governance.
|
||||
|
||||
### Trader
|
||||
|
||||
Escrow, OTC option, Order book. Based on
|
||||
[basecoin-examples](https://github.com/tendermint/basecoin-examples/tree/develop/trader).
|
||||
This may be more appropriate for an external repo.
|
||||
## Example Apps
|
||||
|
||||
See the [Cosmos Academy](https://github.com/cosmos/cosmos-academy) for example applications.
|
Loading…
Reference in New Issue