Merge pull request #180 from tendermint/feature/rige-docs

Feature/rige docs
This commit is contained in:
Ethan Frey 2017-07-24 17:59:24 -04:00 committed by GitHub
commit fb4266249e
4 changed files with 258 additions and 185 deletions

View File

@ -1,17 +1,15 @@
# Basecoin # Quark
_DISCLAIMER: Basecoin is not associated with Coinbase.com, an excellent Bitcoin/Ethereum service._ Quark 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.
Basecoin 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. Quark serves as a reference implementation for how we build ABCI applications
It also provides a general purpose framework for extending the feature-set of the cryptocurrency in Go, and is the framework in which we implement the [Cosmos
by implementing plugins. Hub](https://cosmos.network). **It's easy to use, and doesn't require any
forking** - just implement your plugin, import the quark libraries, and away
Basecoin serves as a reference implementation for how we build ABCI applications in Go, you go with a full-stack blockchain and command line tool for transacting.
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 basecoin libraries,
and away you go with a full-stack blockchain and command line tool for transacting.
WARNING: Currently uses plain-text private keys for transactions and is otherwise not production ready.
## Prerequisites ## Prerequisites
@ -28,10 +26,10 @@ See the [install guide](/docs/guide/install.md) for more details.
## Guide ## Guide
1. Getting started with the [Basecoin basics](/docs/guide/basecoin-basics.md) 1. Getting started with the [Quark basics](/docs/guide/basecoin-basics.md)
1. Learning to [use the plugin system](/docs/guide/basecoin-plugins.md) 1. Learning to [use the plugin system](/docs/guide/basecoin-plugins.md)
1. More features of the [Basecoin tool](/docs/guide/basecoin-tool.md) 1. More features of the [Quark tool](/docs/guide/basecoin-tool.md)
1. Learn how to use [InterBlockchain Communication (IBC)](/docs/guide/ibc.md) 1. Learn how to use [Inter-Blockchain Communication (IBC)](/docs/guide/ibc.md)
1. See [more examples](github.com/tendermint/basecoin-examples) 1. See [more examples](github.com/tendermint/basecoin-examples)

View File

@ -1,32 +1,39 @@
# Quark # Quark
Quarks are the building blocks of atoms. And in a similar vein, this Quarks are the fundamental building blocks of atoms through which DNA, life,
package is a framework for building the cosmos. It gives you all the tools and matter arise. Similarly this package is the core framework for constructing
you need to quickly build up powerful abci applications to run on tendermint, the atom tokens which will power [The Cosmos Network](https://cosmos.network/).
while also providing maximum flexibility to customize aspects of your
application (do you require fees, how do you want to log messages, do you
enable IBC, do you even have a cryptocurrency?)
However, when power and flexibility meet, the result is also some level of 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 complexity and a learning curve. Here is an introduction to the core concepts
embedded in quarks, so you can apply them properly. embedded in Quark.
## Inspiration ## Inspiration
The basic concept came from years of web development. After decades of web The basic concept came from years of web development. A number of patterns
development, a number of patterns have arisen that enabled people to build have arisen in that realm of software which enable people to build remote
remote servers with APIs remarkably quickly and with high stability. servers with APIs remarkably quickly and with high stability. The
I think the ABCI app interface is similar to a web api (DeliverTx is like POST [ABCI](https://github.com/tendermint/abci) application interface is similar to
and Query is like GET and SetOption is like the admin playing with the config a web API (DeliverTx is like POST and Query is like GET and `SetOption` is like
file). Here are some patterns that might be useful: the admin playing with the config file). Here are some patterns that might be
useful:
* MVC - separate data model (storage) from business logic (controllers) * MVC - separate data model (storage) from business logic (controllers)
* Routers - easily direct each request to the appropriate controller * Routers - easily direct each request to the appropriate controller
* Middleware - a series of wrappers that provide global functionality (like * Middleware - a series of wrappers that provide global functionality (like
authentication) to all controllers authentication) to all controllers
* Modules (gems, package, ...) - people can write a self-contained package * Modules (gems, package, ...) - developers can write a self-contained package
with a given set of functionality, which can be imported and reused in with a given set of functionality, which can be imported and reused in other
other apps apps
Also, the idea of different tables/schemas in databases, so you can keep the Also, the idea of different tables/schemas in databases, so you can keep the
different modules safely separated and avoid any accidental (or malicious) different modules safely separated and avoid any accidental (or malicious)
@ -41,6 +48,6 @@ into various applications.
* [Glossary of the terms](glossary.md) * [Glossary of the terms](glossary.md)
* [Standard modules](stdlib.md) * [Standard modules](stdlib.md)
* Guide to building a module * Guide to building a module
* Demo of cli tool * Demo of CLI tool
* IBC in detail * IBC in detail
* Diagrams!!! * Diagrams... Coming Soon!

View File

@ -1,31 +1,33 @@
# Glossary # Glossary
This defines many of the terms that are used in the other documents. If there This glossary defines many terms used throughout documentation of Quark. If
is every a concept that seems unclear, check here. This is mainly to provide there is every a concept that seems unclear, check here. This is mainly to
a background and general understanding of the different words and concepts provide a background and general understanding of the different words and
that are used. Other documents will explain in more detail how to combine concepts that are used. Other documents will explain in more detail how to
these concepts to build a particular application. combine these concepts to build a particular application.
## Transaction ## Transaction (tx)
A transaction is a packet of binary data that contains all information to 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 validate and perform an action on the blockchain. The only other data that it
it interacts with is the current state of the chain (kv store), and it must interacts with is the current state of the chain (key-value store), and
have a deterministic action. The transaction is the main piece of one request. it must have a deterministic action. The tx is the main piece of one request.
We currently make heavy use of go-wire and go-data to provide automatic binary We currently make heavy use of [go-wire](https://github.com/tendermint/go-wire)
and json encodings (and decodings) for objects, even when they embed many and [data](https://github.com/tendermint/go-wire/tree/master/data) to provide
interfaces inside. There is one public `TxMapper` in the basecoin root package, binary and json encodings and decodings for `struct` or interface` objects.
and all modules can register their own transaction types there. This allows us Here, encoding and decoding operations are designed to operate with interfaces
to deserialize the entire tx in one location (even with types defined in other nested any amount times (like an onion!). There is one public `TxMapper`
repos), to easily embed an arbitrary Tx inside another without specifying in the basecoin root package, and all modules can register their own transaction types there. This allows us to deserialize the entire tx in
the specific type, and provide an automatic json representation to provide to one location (even with types defined in other repos), to easily embed
users (or apps) to inspect the chain. 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.
Note how we can wrap any other transaction, add a fee level, and not worry Note how we can wrap any other transaction, add a fee level, and not worry
about the encoding in our module any more? about the encoding in our module any more?
```Go ```golang
type Fee struct { type Fee struct {
Fee coin.Coin `json:"fee"` Fee coin.Coin `json:"fee"`
Payer basecoin.Actor `json:"payer"` // the address who pays the fee Payer basecoin.Actor `json:"payer"` // the address who pays the fee
@ -33,54 +35,68 @@ type Fee struct {
} }
``` ```
## Context ## Context (ctx)
As the request passes through the system, it can pick up information, that must As a request passes through the system, it may pick up information such as the
be carried along with it. Like the authorized it has received from another authorization it has received from another middleware, or the block height the
middleware, or the block height it runs at. This is all deterministic request runs at. In order to carry this information between modules it is
information from the context in which the request runs (based on the tx and saved to the context. further, it all information must be deterministic from
the block it was included in) and can be used to validate the tx. 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.
## Data Store ## Data Store
To be able to provide proofs to tendermint, we keep all data in one key-value To be able to provide proofs to Tendermint, we keep all data in one key-value
store, indexed with a merkle tree. This allows us to easily provide a root (kv) store which is indexed with a merkle tree. This allows for the easy
hash and proofs for queries without requiring complex logic inside each generation of a root hash and proofs for queries without requiring complex
module. Standarizing this also allows powerful light-client tooling as it knows logic inside each module. Standardization of this process also allows powerful
how to verify all data in the store. light-client tooling as any store data may be verified on the fly.
The downside is there is one quite simple interface that the application has The largest limitation of the current implemenation of the kv-store is that
to `Get` and `Set` data. There is not even a range query. Although there are interface that the application must use can only `Get` and `Set` single data
some data structures like queues and range queries that are also in the `state` points. This said, there are some data structures like queues and range
package to provide higher-level functionality in a standard format. 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.
## Isolation ## Isolation
One of the main arguments for blockchain is security. So while we encourage One of the main arguments for blockchain is security. So while we encourage
the use of third-party modules, we must be vigilant against security holes. the use of third-party modules, all developers must be vigilant against
If you use the `stack` package, it will provide two different types of security holes. If you use the
sandboxing for you. [stack](https://github.com/tendermint/basecoin/tree/unstable/stack)
package, it will provide two different types of compartmentalization security.
The first step, is that when `DeliverTx` is called on a module, it is never The first is to limit the working kv-store space of each module. When
given the entire data store, but rather only its own prefixed section. This `DeliverTx` is called for a module, it is never given the entire data store,
is achieved by prefixing all keys transparently with `<module name> + 0x0`, but rather only its own prefixed subset of the store. This is achieved by
using the null byte as a separator. Since module name must be a string, no prefixing all keys transparently with `<module name> + 0x0`, using the null
clever naming scheme can lead to a collision. Inside the module, we can write byte as a separator. Since the module name must be a string, no malicious
anywhere we want, without worry that we have to touch some data that is not ours. 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 step involves the permissions in the context. The context can say The second is to add permissions to the transaction context. The tx context
that this tx was signed by eg. Rigel. But if any module can add that permission, can specify that the tx has been signed by one or multiple specific
it would be too easy to forge accounts. Thus, each permission is associated [actors](https://github.com/tendermint/basecoin/blob/unstable/context.go#L18).
with the module that granted it (in this case `auth`), and if a module tries A tx will only be executed if the permission requirements have been fulfilled.
to add a permission for another module, it will panic. There is also For example the sender of funds must have signed, or 2 out of 3
protection if a module creates a brand new fake context to trick the downstream multi-signature actors must have signed a joint account. To prevent the
modules. 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)),
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
the rules on how to make child contexts, and the stack middleware builder
enforces that the context passed from one level to the next is a valid
child of the original one.
This means that modules can confidently write to their local section of the These security measures ensure that modules can confidently write to their
database and trust the permissions associated with the context, without concern local section of the database and trust the permissions associated with the
of interferance from other modules. (Okay, if you see a bunch of C-code in context, without concern of interference from other modules. (Okay,
the module traversing through all the memory space of the application, then if you see a bunch of C-code in the module traversing through all the
get worried....) memory space of the application, then get worried....)
## Handler ## Handler
@ -89,19 +105,19 @@ into an internal format that is more convenient, but unable to travel over the
wire. The basic interface for any code that modifies state is the `Handler` wire. The basic interface for any code that modifies state is the `Handler`
interface, which provides four methods: interface, which provides four methods:
```Go ```golang
Name() string Name() string
CheckTx(ctx Context, store state.KVStore, tx Tx) (Result, error) CheckTx(ctx Context, store state.KVStore, tx Tx) (Result, error)
DeliverTx(ctx Context, store state.KVStore, tx Tx) (Result, error) DeliverTx(ctx Context, store state.KVStore, tx Tx) (Result, error)
SetOption(l log.Logger, store state.KVStore, module, key, value string) (string, error) SetOption(l log.Logger, store state.KVStore, module, key, value string) (string, error)
``` ```
Note the `Context`, `Store`, and `Tx` as principal carriers of information. And Note the `Context`, `KVStore`, and `Tx` as principal carriers of information.
that Result is always success, and we have a second error return for errors And that Result is always success, and we have a second error return
(which is much more standard go that `res.IsErr()`) for errors (which is much more standard golang that `res.IsErr()`)
The `Handler` interface is designed to be the basis for all modules that The `Handler` interface is designed to be the basis for all modules that
execute transaction, and this can provide a large degree of code execute transactions, and this can provide a large degree of code
interoperability, much like `http.Handler` does in golang web development. interoperability, much like `http.Handler` does in golang web development.
## Middleware ## Middleware
@ -110,16 +126,16 @@ Middleware is a series of processing steps that any request must travel through
before (and after) executing the registered `Handler`. Some examples are a before (and after) executing the registered `Handler`. Some examples are a
logger (that records the time before executing the tx, then outputs info - logger (that records the time before executing the tx, then outputs info -
including duration - after the execution), of a signature checker (which including duration - after the execution), of a signature checker (which
unwraps the tx by one layer, verifies signatutes, and adds the permissions to unwraps the tx by one layer, verifies signatures, and adds the permissions to
the Context before passing the request along). the Context before passing the request along).
In keeping with the standardazation of `http.Handler` and inspired by the In keeping with the standardization of `http.Handler` and inspired by the
super minimal [negroni](https://github.com/urfave/negroni/blob/master/README.md) super minimal [negroni](https://github.com/urfave/negroni/blob/master/README.md)
package, we just provide one more `Middleware` interface, which has an extra package, we just provide one more `Middleware` interface, which has an extra
`next` parameter, and a `Stack` that can wire all the levels together (which `next` parameter, and a `Stack` that can wire all the levels together (which
also gives us a place to perform isolation of each step). also gives us a place to perform isolation of each step).
```Go ```golang
Name() string Name() string
CheckTx(ctx Context, store state.KVStore, tx Tx, next Checker) (Result, error) CheckTx(ctx Context, store state.KVStore, tx Tx, next Checker) (Result, error)
DeliverTx(ctx Context, store state.KVStore, tx Tx, next Deliver) (Result, error) DeliverTx(ctx Context, store state.KVStore, tx Tx, next Deliver) (Result, error)
@ -128,19 +144,20 @@ also gives us a place to perform isolation of each step).
## Modules ## Modules
A module is a set of functionality that is more or less self-sufficient. It A module is a set of functionality which should be typically designed as
usually contains the following pieces: self-sufficient. Common elements of a module are:
* transaction types (either end transactions, or transaction wrappers) * transaction types (either end transactions, or transaction wrappers)
* custom error codes * custom error codes
* data models (to persist in the kv store) * data models (to persist in the kv-store)
* handler (to handle any end transactions) * handler (to handle any end transactions)
* middleware (to handler any wrapper transactions) * middleware (to handler any wrapper transactions)
To enable a module, you must add the appropriate middleware (if any) to the To enable a module, you must add the appropriate middleware (if any) to the
stack in main.go, as well as adding the handler (if any) to the dispatcher. stack in `main.go` for the client application (Quark default:
One the stack is compiled into a `Handler`, then all tx are handled by the `basecli/main.go`), as well as adding the handler (if any) to the dispatcher
proper module. (Quark default: `app/app.go). Once the stack is compiled into a `Handler`,
then each tx is handled by the appropriate module.
## Dispatcher ## Dispatcher
@ -163,47 +180,49 @@ This all seems a bit of magic, but really just making use of the other magic
thing you need to remember is to use the following pattern, then all the tx thing you need to remember is to use the following pattern, then all the tx
will be properly routed: will be properly routed:
```Go ```golang
const ( const (
NameCoin = "coin" NameCoin = "coin"
TypeSend = NameCoin + "/send" TypeSend = NameCoin + "/send"
) )
``` ```
## IPC (Inter-Plugin Communication) ## Inter-Plugin Communication (IPC)
But wait, there's more... since we have isolated all the modules from each 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. other, we need to allow some way for them to interact in a controlled fashion.
Some examples are the `fee` middleware, which wants to deduct coins from One example is the `fee` middleware, which wants to deduct coins from the
the calling account (in the `coin` module), or a vote that requires a payment. calling account and can accomplished most easilty with the `coin` module.
If we want to make a call from the middleware, this is relatively simple. If we want to make a call from the middleware, this is relatively simple. The
The middleware already has a handle to the `next` Handler, which will middleware already has a handle to the `next` Handler, which will execute the
execute the rest of the stack. It can simple create a new SendTx and pass rest of the stack. It can simple create a new SendTx and pass it down the
it down the stack. If it returns success, then do the rest of the processing stack. If it returns success, then do the rest of the processing (and send the
(and send the original tx down the stack), otherwise abort. original tx down the stack), otherwise abort.
However, if one `Handler` inside the `Dispatcher` wants to do this, it However, if one `Handler` inside the `Dispatcher` wants to do this, it becomes
becomes more complex. The solution is that the `Dispatcher` accepts not more complex. The solution is that the `Dispatcher` accepts not a `Handler`,
a `Handler`, but a `Dispatchable`, which looks like a middleware, except but a `Dispatchable`, which looks like a middleware, except that the `next`
that the `next` argument is a callback to the dispatcher to execute a argument is a callback to the dispatcher to execute a sub-transaction. If a
sub-transaction. If a module doesn't want to use this functionality, module doesn't want to use this functionality, it can just implement `Handler`
it can just implement `Handler` and call `stack.WrapHandler(h)` to convert and call `stack.WrapHandler(h)` to convert it to a `Dispatchable` that never
it to a `Dispatchable` that never uses the callback. uses the callback.
One example of this is the counter app, which can optionally accept a payment. 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 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 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. [counter
plugin](https://github.com/tendermint/basecoin/blob/unstable/docs/guide/counter/plugins/counter/counter.go)
for a better idea.
## Permissions ## Permissions
This system requires a more complex permissioning system to allow the modules IPC requires a more complex permissioning system to allow the modules to have
to have limited access to each other. Also to allow more types of permissions limited access to each other. Also to allow more types of permissions than
than simple public key signatures. So, rather than just use an address to simple public key signatures. So, rather than just use an address to identify
identify who is performing an action, we can use a more complex structure: who is performing an action, we can use a more complex structure:
```Go ```golang
type Actor struct { type Actor struct {
ChainID string `json:"chain"` // this is empty unless it comes from a different chain ChainID string `json:"chain"` // this is empty unless it comes from a different chain
App string `json:"app"` // the app that the actor belongs to App string `json:"app"` // the app that the actor belongs to
@ -211,32 +230,70 @@ type Actor struct {
} }
``` ```
Here, the `Actor` abstracts any address that can authorize actions, hold funds,
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 `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 on `App` and `Address`. For a signature, the App is `auth`, and any modules
check to see if a specific public key address signed like this can check to see if a specific public key address signed like this
`ctx.HasPermission(auth.SigPerm(addr))`. However, we can also authorize a `ctx.HasPermission(auth.SigPerm(addr))`. However, we can also authorize a tx
tx with `roles`, which handles multi-sig accounts, it checks if there were with `roles`, which handles multi-sig accounts, it checks if there were enough
enough signatures by checking as above, then it can add the role permission like signatures by checking as above, then it can add the role permission like `ctx
`ctx = ctx.WithPermissions(NewPerm(assume.Role))` = ctx.WithPermissions(NewPerm(assume.Role))`
In addition to permissioning, the Actors are addresses just like public key In addition to permissioning, the Actors are addresses just like public key
addresses. So one can create a mulit-sig role, then send coin there, which addresses. So one can create a mulit-sig role, then send coin there, which can
can only be moved upon meeting the authorization requirements from that module. 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 `coin` doesn't even know the existence of `roles` and one could build any other
other sort of module to provide permissions (like bind the outcome of an sort of module to provide permissions (like bind the outcome of an election to
election to move coins or to modify the accounts on a role). move coins or to modify the accounts on a role).
One idea (not implemented) is to provide scopes on the permissions. Right now, 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 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 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 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) this signature authorizes. The [oauth
also has to deal with a similar problem, and maybe could provide some inspiration. protocol](https://api.slack.com/docs/oauth-scopes) also has to deal with a
similar problem, and maybe could provide some inspiration.
## Replay Protection ## Replay Protection
Is implemented as middleware. Rigel can add more info here. Or look In order to prevent [replay
at [the github issue](https://github.com/tendermint/basecoin/issues/160) attacks](https://en.wikipedia.org/wiki/Replay_attack) a multi account nonce system
has been constructed as a module, which can be found in
`modules/nonce`. By adding the nonce module to the stack, each
transaction is verified for authenticity against replay attacks. This is
achieved by requiring that a new signed copy of the sequence number which must
be exactly 1 greater than the sequence number of the previous transaction. A
distinct sequence number is assigned per chain-id, application, and group of
signers. Each sequence number is tracked as a nonce-store entry where the key
is the marshaled list of actors after having been sorted by chain, app, and
address.
```golang
// Tx - Nonce transaction structure, contains list of signers and current sequence number
type Tx struct {
Sequence uint32 `json:"sequence"`
Signers []basecoin.Actor `json:"signers"`
Tx basecoin.Tx `json:"tx"`
}
```
By distinguishing sequence numbers across groups of Signers, multi-signature
Actors need not lock up use of their Address while waiting for all the members
of a multi-sig transaction to occur. Instead only the multi-sig account will
be locked, while other accounts belonging to that signer can be used and signed
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
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) ## IBC (Inter-Blockchain Communication)

View File

@ -1,96 +1,106 @@
# Standard Library # Standard Library
The quarks framework comes with a number of standard modules that provide a lot The Quark framework comes bundled with a number of standard modules that
of common functionality that is useful to a wide variety of applications, provide common functionality useful across a wide variety of applications.
and also provide good examples to use when developing your own modules. Before Example usage of the modules is also provided. It is recommended to investigate
starting to write code, see if the functionality is already here. if desired functionality is already provided before developing new modules.
## Basic Middleware ## Basic Middleware
### Logging ### Logging
`modules.base.Logger` is a middleware that records basic info on CheckTx, `modules.base.Logger` is a middleware that records basic info on `CheckTx`,
DeliverTx, and SetOption, along with timing in microseconds. It can be installed `DeliverTx`, and `SetOption`, along with timing in microseconds. It can be
standard at the top of all middleware stacks, or replace it with your own installed standard at the top of all middleware stacks, or replaced with your
Middleware if you want to record more custom information with each request. own middleware if you want to record custom information with each request.
### Recovery ### Recovery
To avoid accidental panics (eg. bad go-wire decoding) killing the abci app, To avoid accidental panics (e.g. bad go-wire decoding) killing the ABCI app,
wrap the stack with `stack.Recovery`, which catches all panics and returns wrap the stack with `stack.Recovery`, which catches all panics and returns
them as errors, so they can be handled normally. them as errors, so they can be handled normally.
### Signatures ### Signatures
The first layer of the tx contains the signatures to authorize it. This is then The first layer of the tx contains the signatures to authorize it. This is
verfied by `modules.auth.Signatures`. All tx may have one or multiple signatures then verified by `modules.auth.Signatures`. All tx may have one or multiple
which are then processed and verified by this middleware and then passed down signatures which are then processed and verified by this middleware and then
the stack. passed down the stack.
### Chain ### Chain
The next layer of a tx (in the standard stack) binds the tx to a specific 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 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 multisig being delayed 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 months before being committed to the chain. This functionality is provided in
`modules.base.Chain` `modules.base.Chain`
### Nonce ### Nonce
To avoid replay protection within one chain, we want a nonce associated To avoid replay attacks, a nonce can be associated with each actor. A separate
with each account. Rather than force everything to use coins as a payment,or force each module to implement its own replay protection, each tx is wraped with a nonce and nonce is used for each distinct group signers required for a transaction as
the account it belongs to. This must be one higher than the last request or well as for each separate application and chain-id. This creates replay
the request is rejected. This is implemented in `modules.nonce.ReplayCheck` 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.
You can also take a look at the [design discussion](https://github.com/tendermint/basecoin/issues/160) 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`
If you're interested checkout this [design
discussion](https://github.com/tendermint/basecoin/issues/160).
### Fees ### Fees
An optional feature, but useful on many chains, is charging a fee for every An optional feature, but useful on many chains, is charging transaction fees. A
transaction. A simple implementation of this is provided in simple implementation of this is provided in `modules.fee.SimpleFeeMiddleware`.
`modules.fee.SimpleFeeMiddleware`. A fee currency and minimum amount are A fee currency and minimum amount are defined in the constructor (eg. in code).
defined in the constructor (eg. in code). If the minimum amount is 0, then If the minimum amount is 0, then the fee is optional. If it is above 0, then
the fee is optional. If it is above 0, then every tx with insufficient fee is every tx with insufficient fee is rejected. This fee is deducted from the
rejected. This fee is deducted from the payers account before executing any payers account before executing any other transaction.
other transaction.
This module depends on the `coin` module. This module is dependent on the `coin` module.
## Other Apps ## Other Apps
### Coin ### Coin
What would a crypto-currency be without tokens? The sendtx logic from basecoin What would a crypto-currency be without tokens? The `SendTx` logic from earlier
was extracted into one module, which is now optional, meaning most of the other implementations of basecoin was extracted into one module, which is now
functionality would also work in a system with no built-in tokens, such as optional, meaning most of the other functionality will also work in a system
a private network that provides another access control mechanism. with no built-in tokens, such as a private network that provides other access
control mechanisms.
`modules.coin.Handler` defines a Handler that maintains a number of accounts `modules.coin.Handler` defines a Handler that maintains a number of accounts
along with a set of various tokens, supporting multiple denominations. The along with a set of various tokens, supporting multiple token denominations.
main access is `SendTx`, which can support any type of actor (other apps as The main access is `SendTx`, which can support any type of actor (other apps as
well as public key addresses), and is a building block for any other app that well as public key addresses) and is a building block for any other app that
requires some payment solution, like fees or trader. requires some payment solution, like fees or trader.
### Roles ### Roles
Roles encapsulates what are typically called N-of-M multi-signatures accounts Roles encapsulates 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 in the crypto world. However, I view this as a type of role or group, which can
be the basis for building a permision system. For example, a set of people could be the basis for building a permission system. For example, a set of people
be called registrars, which can authorize a new IBC chain, and need eg. 2 out could be called registrars, which can authorize a new IBC chain, and need eg. 2
of 7 signatures to approve it. out of 7 signatures to approve it.
Currently, one can create a role with `modules.roles.Handler`, and assume one Currently, one can create a role with `modules.roles.Handler`, and assume one
of those roles by wrapping another transaction with `AssumeRoleTx`, which is of those roles by wrapping another transaction with `AssumeRoleTx`, which is
processed by `modules.roles.Middleware`. Updating the set of actors in processed by `modules.roles.Middleware`. Updating the set of actors in
a role is planned in the near future. a role is planned in the near future.
### IBC ### Inter-Blockchain Communication (IBC)
IBC, or inter-blockchain communication, is the cornerstone of cosmos, and built IBC, is the cornerstone of The Cosmos Network, and is built into the quark
into the quark framework as a basic primative. To properly understand these framework as a basic primitive. To fully grasp these concepts requires
concepts requires a much longer explanation, but in short, the chain works a much longer explanation, but in short, the chain works as a light-client to
as a light-client to another chain and maintains input and output queue to another chain and maintains input and output queue to send packets with that
send packets with that chain. chain. This mechanism allows blockchains to prove the state of their respective
blockchains to each other ultimately invoke inter-blockchain transactions.
Most functionality is implemented in `modules.ibc.Handler`. Registering a chain Most functionality is implemented in `modules.ibc.Handler`. Registering a chain
is a seed of trust that requires verification of the proper seed (or genesis is a seed of trust that requires verification of the proper seed (or genesis
@ -100,7 +110,7 @@ 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 chain. Also, modules can initiate an outgoing IBC message to another chain
by calling `CreatePacketTx` over IPC (inter-plugin communication) with a tx by calling `CreatePacketTx` over IPC (inter-plugin communication) with a tx
that belongs to their module. (This must be explicitly authorized by the 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 same module, so only the eg. coin module can authorize a `SendTx` to another
chain). chain).
`PostPacketTx` can post a tx that was created on another chain along with the `PostPacketTx` can post a tx that was created on another chain along with the
@ -127,6 +137,7 @@ governance.
### Trader ### Trader
Escrow, OTC option, Order book. Based on [basecoin-examples](https://github.com/tendermint/basecoin-examples/tree/develop/trader). This may be more appropriate Escrow, OTC option, Order book. Based on
for an external repo. [basecoin-examples](https://github.com/tendermint/basecoin-examples/tree/develop/trader).
This may be more appropriate for an external repo.