Added some notes on basecoin intro

This commit is contained in:
Ethan Frey 2017-02-08 13:18:26 +01:00 committed by Ethan Buchman
parent a50146d850
commit 6f173a44a9
6 changed files with 46 additions and 37 deletions

View File

@ -2,12 +2,12 @@
DISCLAIMER: Basecoin is not associated with Coinbase.com, an excellent Bitcoin/Ethereum service.
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.
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.
It also provides a general purpose framework for extending the feature-set of the cryptocurrency
by implementing plugins.
Basecoin 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).
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.
@ -18,8 +18,9 @@ WARNING: Currently uses plain-text private keys for transactions and is otherwis
We use glide for dependency management. The prefered way of compiling from source is the following:
```
go get -d github.com/tendermint/basecoin/cmd/basecoin
go get -u github.com/tendermint/basecoin
cd $GOPATH/src/github.com/tendermint/basecoin
git checkout develop # (until we release v0.9)
make get_vendor_deps
make install
```

View File

@ -7,6 +7,8 @@ Here we explain how to get started with a simple Basecoin blockchain, and how to
Make sure you have [basecoin installed](install.md).
You will also need to [install tendermint](https://tendermint.com/intro/getting-started/download).
**Note** All code is on the 0.9 pre-release branch, you may have to [install tendermint from source](https://tendermint.com/docs/guides/install) until 0.9 is released. (Make sure to add `git checkout develop` to the linked install instructions)
## Initialization
Basecoin is an ABCI application that runs on Tendermint, so we first need to initialize Tendermint:
@ -33,10 +35,10 @@ cd $GOPATH/src/github.com/tendermint/basecoin/data
The directory contains a genesis file and two private keys.
You can generate your own private keys with `tendermint gen_validator`,
You can generate your own private keys with `tendermint gen_validator`,
and construct the `genesis.json` as you like.
Note, however, that you must be careful with the `chain_id` field,
as every transaction must contain the correct `chain_id`
Note, however, that you must be careful with the `chain_id` field,
as every transaction must contain the correct `chain_id`
(default is `test_chain_id`).
## Start
@ -53,7 +55,7 @@ This will initialize the chain with the `genesis.json` file from the current dir
basecoin start --in-proc --dir PATH/TO/CUSTOM/DATA
```
Note that `--in-proc` stands for "in process", which means
Note that `--in-proc` stands for "in process", which means
basecoin will be started with the Tendermint node running in the same process.
To start Tendermint in a separate process instead, use:
@ -68,7 +70,7 @@ tendermint node
```
In either case, you should see blocks start streaming in!
Note, however, that currently basecoin currently requires the
Note, however, that currently basecoin currently requires the
`develop` branch of tendermint for this to work.
## Send transactions
@ -122,10 +124,10 @@ See `basecoin tx send --help` for additional details.
The `tx send` command creates and broadcasts a transaction of type `SendTx`,
which is only useful for moving tokens around.
Fortunately, Basecoin supports another transaction type, the `AppTx`,
Fortunately, Basecoin supports another transaction type, the `AppTx`,
which can trigger code registered via a plugin system.
In the [next tutorial](example-plugin.md),
we demonstrate how to implement a plugin
In the [next tutorial](example-plugin.md),
we demonstrate how to implement a plugin
and extend the CLI to support new transaction types!
But first, you may want to learn a bit more about [Basecoin's design](basecoin-design.md)

View File

@ -30,7 +30,7 @@ type Coin struct {
```
Accounts are serialized and stored in a Merkle tree using the account's address as the key,
In particular, an account is stored in the Merkle tree under the key `base/a/<address>`,
In particular, an account is stored in the Merkle tree under the key `base/a/<address>`,
where `<address>` is the address of the account.
In Basecoin, the address of an account is the 20-byte `RIPEMD160` hash of the public key.
The Merkle tree used in Basecoin is a balanced, binary search tree, which we call an [IAVL tree](https://github.com/tendermint/go-merkle).
@ -44,8 +44,8 @@ The `SendTx` is structured as follows:
```
type SendTx struct {
Gas int64 `json:"gas"`
Fee Coin `json:"fee"`
Gas int64 `json:"gas"`
Fee Coin `json:"fee"`
Inputs []TxInput `json:"inputs"`
Outputs []TxOutput `json:"outputs"`
}
@ -64,24 +64,26 @@ type TxOutput struct {
}
```
There are a few things to note. First, the `SendTx` includes a field for `Gas` and `Fee`.
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.
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,
In tendermint, the `Fee` is meant to be used by the validators to inform the ordering of transactions, like in bitcoin. And the `Gas` is meant to be used by the application plugin to control its execution. There is currently no means to pass `Fee` information to the tendermint validators, but it will come soon...
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.
at once in an atomic transaction. Thus, the `SendTx` can serve as a basic unit of decentralized exchange. When using multiple inputs and outputs, you must make sure that the sum of coins of the inputs equals the sum of coins of the outputs (no creating money), and that all accounts that provide inputs have signed the transaction.
## Plugins
Basecoin actually defines a second transaction type, the `AppTx`,
Basecoin actually defines a second transaction type, the `AppTx`,
which enables the functionality to be extended via custom plugins.
To learn more about the `AppTx` and plugin system, see the [plugin design document](plugin-design.md).
To implement your first plugin, see [plugin tutorial](example-plugin.md).

View File

@ -41,9 +41,9 @@ func main() {
It creates the CLI, exactly like the `basecoin` one.
However, if we want our plugin to be active,
we need to make sure it is registered with the application.
In addition, if we want to send transactions to our plugin,
In addition, if we want to send transactions to our plugin,
we need to add a new command to the CLI.
This is where the `cmd.go` comes in.
This is where the `cmd.go` comes in.
## Commands
@ -154,7 +154,7 @@ func cmdExamplePluginTx(c *cli.Context) error {
We read the flag from the CLI library, and then create the example transaction.
Remember that Basecoin itself only knows about two transaction types, `SendTx` and `AppTx`.
All plugin data must be serialized (ie. encoded as a byte-array)
All plugin data must be serialized (ie. encoded as a byte-array)
and sent as data in an `AppTx`. The `commands.AppTx` function does this for us -
it creates an `AppTx` with the corresponding data, signs it, and sends it on to the blockchain.
@ -162,10 +162,12 @@ it creates an `AppTx` with the corresponding data, signs it, and sends it on to
Ok, now we're ready to actually look at the implementation of the plugin in `plugin.go`.
Note I'll leave out some of the methods as they don't serve any purpose for this example,
but are necessary boilerplate.
Your plugin may have additional requirements that utilize these other plugins.
but are necessary boilerplate.
Your plugin may have additional requirements that utilize these other methods.
Here's what's relevant for us:
**TODO** make `StateKey` `stateKey`? No need to expose this outside the package.
```
type ExamplePluginState struct {
Counter int
@ -276,7 +278,8 @@ if len(stateBytes) > 0 {
}
```
Note the state is stored under `ep.StateKey()`, which is defined above as `ExamplePlugin.State`.
Note the state is stored under `ep.StateKey()`, which is defined above as `ExamplePlugin.State`. Also note, that we do nothing if there is no existing state data. Is that a bug? No, we just make use of go's variable initialization, that `pluginState` will contain a `Counter` value of 0. If your app needs more initialization than empty variables, then do this logic here in an `else` block.
Finally, we can update the state's `Counter`, and save the state back to the store:
```
@ -353,7 +356,7 @@ tendermint unsafe_reset_all
```
Great, now we're ready to go.
To start the blockchain, simply run
To start the blockchain, simply run
```
example-plugin start --in-proc
@ -396,7 +399,7 @@ example-plugin query ExamplePlugin.State
```
Note the `"value":"0101"` piece. This is the serialized form of the state,
which contains only an integer.
which contains only an integer.
If we send another transaction, and then query again, we'll see the value increment:
```
@ -404,14 +407,14 @@ example-plugin tx example --valid --amount 1 --coin gold --chain_id example-chai
example-plugin query ExamplePlugin.State
```
Neat, right? Notice how the result of the query comes with a proof.
Neat, right? Notice how the result of the query comes with a proof.
This is a Merkle proof that the state is what we say it is.
In a latter [tutorial on Interblockchain Communication](ibc.md),
we'll put this proof to work!
## Next Stpes
In this tutorial we demonstrated how to create a new plugin and how to extend the
In this tutorial we demonstrated how to create a new plugin and how to extend the
basecoin CLI to activate the plugin on the blockchain and to send transactions to it.
Hopefully by now you have some ideas for your own plugin, and feel comfortable implementing them.

View File

@ -4,12 +4,12 @@ One of the most exciting elements of the Cosmos Network is the InterBlockchain C
which enables interoperability across different blockchains.
The simplest example of using the IBC protocol is to send a data packet from one blockchain to another.
We implemented IBC as a basecoin plugin.
We implemented IBC as a basecoin plugin.
and here we'll show you how to use the Basecoin IBC-plugin to send a packet of data across blockchains!
Please note, this tutorial assumes you are familiar with [Basecoin plugins](/docs/guide/plugin-design.md)
and with the [Basecoin CLI](/docs/guide/basecoin-basics), but we'll explain how IBC works.
You may also want to see the tutorials on [a simple example plugin](example-plugin.md)
You may also want to see the tutorials on [a simple example plugin](example-plugin.md)
and the list of [more advanced plugins](more-examples.md).
The IBC plugin defines a new set of transactions as subtypes of the `AppTx`.
@ -32,8 +32,8 @@ next block. Thus, each block contains a field called `LastCommit`, which
contains the votes responsible for committing the previous block, and a field
in the block header called `AppHash`, which refers to the merkle root hash of
the application after processing the transactions from the previous block. So,
if we want to verify some state from height H, we need the signatures and root
hash from the header at height H+1.
if we want to verify the `AppHash` from height H, we need the signatures from `LastCommit` at height H+1. (And remember that this `AppHash` only contains the results from all transactions up to and including block H-1)
Unlike Proof-of-Work, the light-client protocol does not need to download and
check all the headers in the blockchain - the client can always jump straight
@ -147,7 +147,7 @@ and the resulting state root is not included until the next block.
### IBC State
Now that we've seen all the transaction types, let's talk about the state.
Each chain stores some IBC state in its merkle tree.
Each chain stores some IBC state in its merkle tree.
For each chain being tracked by our chain, we store:
```
@ -179,7 +179,7 @@ The results of a query can thus be used as proof in an `IBCPacketPostTx`.
Now that we have all the background knowledge, let's actually walk through the tutorial.
Make sure you have installed
Make sure you have installed
[tendermint](https://tendermint.com/intro/getting-started/download) and
[adam](/docs/guide/install.md).

View File

@ -3,8 +3,9 @@
We use glide for dependency management. The prefered way of compiling from source is the following:
```
go get -d github.com/tendermint/basecoin/cmd/basecoin
go get -u github.com/tendermint/basecoin
cd $GOPATH/src/github.com/tendermint/basecoin
git checkout develop # (until we release v0.9)
make get_vendor_deps
make install
```