docs: design, examples

This commit is contained in:
Ethan Buchman 2017-02-05 00:43:55 -05:00
parent 8fda433847
commit cb253cbdf4
4 changed files with 153 additions and 41 deletions

View File

@ -40,7 +40,7 @@ See `basecoin --help` and `basecoin [cmd] --help` for more details`.
1. Make your own [cryptocurrency using Basecoin plugins](/docs/guide/example-counter.md)
1. Learn more about [plugin design](/docs/guide/plugin-design.md)
1. See some [more example applications](/docs/guide/more-examples.md)
1. Learn how to use [InterBlockchain Communication (IBC)](ibc.md)
1. Learn how to use [InterBlockchain Communication (IBC)](/docs/guide/ibc.md)
1. [Deploy testnets](deployment.md) running your basecoin application.

View File

@ -0,0 +1,81 @@
# Basecoin Design
Basecoin is designed to be a simple cryptocurrency application with limitted built-in functionality,
but with the capacity to be extended by arbitrary plugins.
Its basic data structures are inspired by Ethereum, but it is much simpler, as there is no built in virtual machine.
## Accounts
The Basecoin state consists entirely of a set of accounts.
Each account contains an ED25519 public key,
a balance in many different coin denominations,
and a strictly increasing sequence number for replay protection.
This type of account was directly inspired by accounts in Ethereum,
and is unlike Bitcoin's use of Unspent Transaction Outputs (UTXOs).
Note Basecoin is a multi-asset cryptocurrency, so each account can have many different kinds of tokens.
Accounts are serialized and stored in a Merkle tree using the account's address as the key,
where the address is the RIPEMD160 hash of the public key.
In particular, an account is stored in the Merkle tree under the key `base/a/<address>`,
where `<address>` is the 20-byte address of the account.
We use an implementation of a Merkle, balanced, binary search tree, also known as an [IAVL tree](https://github.com/tendermint/go-merkle).
## Transactions
Basecoin defines a simple transaction type, the `SendTx`, which allows tokens to be sent to other accounts.
The `SendTx` takes a list of inputs and a list of outputs,
and transfers all the tokens listed in the inputs from their corresponding accounts to the accounts listed in the output.
The `SendTx` is structured as follows:
```
type SendTx struct {
Gas int64 `json:"gas"`
Fee Coin `json:"fee"`
Inputs []TxInput `json:"inputs"`
Outputs []TxOutput `json:"outputs"`
}
type TxInput struct {
Address []byte `json:"address"` // Hash of the PubKey
Coins Coins `json:"coins"` //
Sequence int `json:"sequence"` // Must be 1 greater than the last committed TxInput
Signature crypto.Signature `json:"signature"` // Depends on the PubKey type and the whole Tx
PubKey crypto.PubKey `json:"pub_key"` // Is present iff Sequence == 0
}
type TxOutput struct {
Address []byte `json:"address"` // Hash of the PubKey
Coins Coins `json:"coins"` //
}
type Coins []Coin
type Coin struct {
Denom string `json:"denom"`
Amount int64 `json:"amount"`
}
```
There are a few things to note. First, the `SendTx` includes a field for `Gas` and `Fee`.
The `Gas` limits the total amount of computation that can be done by the transaction,
while the `Fee` refers to the total amount paid in fees.
This is slightly different from Ethereum's concept of `Gas` and `GasPrice`,
where `Fee = Gas x GasPrice`. In Basecoin, the `Gas` and `Fee` are independent,
and the `GasPrice` is implicit.
Second, notice that the `PubKey` only needs to be sent for `Sequence == 0`.
After that, it is stored under the account in the Merkle tree and subsequent transactions can exclude it,
using only the `Address` to refer to the sender. Ethereum does not require public keys to be sent in transactions
as it uses a different elliptic curve scheme which enables the public key to be derrived from the signature itself.
Finally, note that the use of multiple inputs and multiple outputs allows us to send many different types of tokens between many different accounts
at once in an atomic transaction. Thus, the `SendTx` can serve as a basic unit of decentralized exchange.
## Next steps
1. Make your own [cryptocurrency using Basecoin plugins](example-counter.md)
1. Learn more about [plugin design](plugin-design.md)
1. See some [more example applications](more-examples.md)
1. Learn how to use [InterBlockchain Communication (IBC)](ibc.md)
1. [Deploy testnets](deployment.md) running your basecoin application.

View File

@ -1,8 +1,17 @@
# Plugin Examples
Now that we've seen how to use Basecoin, talked about the design,
and looked at how to implement a simple plugin, let's take a look at some more interesting examples.
## Mintcoin
Basecoin does not provide any functionality for adding new tokens to the system.
The state is endowed with tokens by a `genesis.json` file which is read once when the system is first started.
From there, tokens can be sent to other accounts, even new accounts, but it's impossible to add more tokens to the system.
For this, we need a plugin.
You just read about the amazing [plugin system](https://github.com/tendermint/basecoin/blob/develop/Plugins.md), and want to use it to print your own money. Me too! Let's get started with a simple plugin extension to basecoin, called [mintcoin](./mintcoin/README.md). This plugin lets you register one or more accounts as "central bankers", who can unilaterally issue more currency into the system. It also serves as a simple test-bed to see how one can not just build a plugin, but also take advantage of existing codebases to provide a simple cli to use it.
The `mintcoin` plugin lets you register one or more accounts as "central bankers",
who can unilaterally issue more currency into the system.
## Financial Instruments

View File

@ -1,50 +1,72 @@
# Basecoin Plugins
Basecoin is an extensible cryptocurrency module.
Each Basecoin account contains a ED25519 public key,
a balance in many different coin denominations,
and a strictly increasing sequence number for replay protection (like in Ethereum).
Accounts are serialized and stored in a merkle tree using the account's address as the key,
where the address is the RIPEMD160 hash of the public key.
Basecoin implements a simple cryptocurrency, which is useful in and of itself,
but is far more useful if it can support additional functionality.
Here we describe how that functionality can be achieved through a plugin system.
Sending tokens around is done via the `SendTx`, which takes a list of inputs and a list of outputs,
and transfers all the tokens listed in the inputs from their corresponding accounts to the accounts listed in the output.
The `SendTx` is structured as follows:
## AppTx
In addition to the `SendTx`, Basecoin also defines another transaction type, the `AppTx`:
```
type SendTx struct {
Gas int64 `json:"gas"` // Gas
Fee Coin `json:"fee"` // Fee
Inputs []TxInput `json:"inputs"`
Outputs []TxOutput `json:"outputs"`
type AppTx struct {
Gas int64 `json:"gas"`
Fee Coin `json:"fee"`
Input TxInput `json:"input"`
Name string `json:"type"` // Name of the plugin
Data []byte `json:"data"` // Data for the plugin to process
}
type TxInput struct {
Address []byte `json:"address"` // Hash of the PubKey
Coins Coins `json:"coins"` //
Sequence int `json:"sequence"` // Must be 1 greater than the last committed TxInput
Signature crypto.Signature `json:"signature"` // Depends on the PubKey type and the whole Tx
PubKey crypto.PubKey `json:"pub_key"` // Is present iff Sequence == 0
}
type TxOutput struct {
Address []byte `json:"address"` // Hash of the PubKey
Coins Coins `json:"coins"` //
}
type Coins []Coin
type Coin struct {
Denom string `json:"denom"`
Amount int64 `json:"amount"`
}
```
Note it also includes a field for `Gas` and `Fee`. The `Gas` limits the total amount of computation that can be done by the transaction,
while the `Fee` refers to the total amount paid in fees. This is slightly different from Ethereum's concept of `Gas` and `GasPrice`,
where `Fee = Gas x GasPrice`. In Basecoin, the `Gas` and `Fee` are independent.
The `AppTx` enables Basecoin to be extended with arbitrary additional functionality through the use of plugins.
The `Name` field in the `AppTx` refers to the particular plugin which should process the transasaction,
and the `Data` field of the `AppTx` is the data to be forwarded to the plugin for processing.
Note the `AppTx` also has a `Gas` and `Fee`, with the same meaning as for the `SendTx`.
It also includes a single `TxInput`, which specifies the sender of the transaction,
and some coins that can be forwarded to the plugin as well.
## Plugins
A plugin is simply a Go package that implements the `Plugin` interface:
```
type Plugin interface {
// Name of this plugin, should be short.
Name() string
// Run a transaction from ABCI DeliverTx
RunTx(store KVStore, ctx CallContext, txBytes []byte) (res abci.Result)
// Other ABCI message handlers
SetOption(store KVStore, key string, value string) (log string)
InitChain(store KVStore, vals []*abci.Validator)
BeginBlock(store KVStore, height uint64)
EndBlock(store KVStore, height uint64) []*abci.Validator
}
type CallContext struct {
CallerAddress []byte // Caller's Address (hash of PubKey)
CallerAccount *Account // Caller's Account, w/ fee & TxInputs deducted
Coins Coins // The coins that the caller wishes to spend, excluding fees
}
```
The workhorse of the plugin is `RunTx`, which is called when an `AppTx` is processed.
The `Data` from the `AppTx` is passed in as the `txBytes`,
while the `Input` from the `AppTx` is used to populate the `CallContext`.
Note that `RunTx` also takes a `KVStore` - this is an abstraction for the underlying Merkle tree which stores the account data.
By passing this to the plugin, we enable plugins to update accounts in the Basecoin state directly,
and also to store arbitrary other information in the state.
In this way, the functionality and state of a Basecoin-derrived cryptocurrency can be greatly extended.
One could imagine going so far as to implement the Ethereum Virtual Machine as a plugin!
Basecoin also defines another transaction type, the `AppTx`:
## Next steps
1. Examples of [Basecoin plugins](more-examples.md)
1. Learn how to use [InterBlockchain Communication (IBC)](ibc.md)
1. [Deploy testnets](deployment.md) running your basecoin application.