From 9b0f4fc65031d688b8ddba480e62320393cfac61 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 20 Jun 2017 21:36:04 -0400 Subject: [PATCH] docs: update basics and plugins --- docs/guide/basecoin-basics.md | 126 +++++++++++++++++++-------------- docs/guide/basecoin-plugins.md | 59 +++++++-------- 2 files changed, 98 insertions(+), 87 deletions(-) diff --git a/docs/guide/basecoin-basics.md b/docs/guide/basecoin-basics.md index 9692f31099..716fddb970 100644 --- a/docs/guide/basecoin-basics.md +++ b/docs/guide/basecoin-basics.md @@ -14,56 +14,51 @@ go get -u github.com/tendermint/basecoin/cmd/... If you have trouble, see the [installation guide](install.md). +Note the above command installs two binaries: `basecoin` and `basecli`. +The former is the running node. The latter is a command-line light-client. + +## Generate some keys + +Let's generate two keys, one to receive an initial allocation of coins, +and one to send some coins to later: + +``` +# WARNING: this will wipe out any existing info in the ~/.basecli dir +# including private keys, don't run if you have lots of local state already +basecli reset_all +basecli keys new cool +basecli keys new friend +``` + +You'll need to enter passwords. You can view your key names and addresses with `basecli keys list`, +or see a particular key's address with `basecli keys get `. + ## Initialize Basecoin + To initialize a new Basecoin blockchain, run: ``` # WARNING: this will wipe out any existing info in the ~/.basecoin dir # don't run if you have lots of local state already rm -rf ~/.basecoin -basecoin init +basecoin init
+``` + +If you prefer not to copy-paste, you can provide the address programatically: + +``` +basecoin init $(basecli keys get cool | awk '{print $2}') ``` This will create the necessary files for a Basecoin blockchain with one -validator and one account in `~/.basecoin`. For more options on setup, see the +validator and one account (corresponding to your key) in `~/.basecoin`. For more options on setup, see the [guide to using the Basecoin tool](/docs/guide/basecoin-tool.md). -For this example, we will change the genesis account to a new account named -`cool`. First create a new account: - -``` -# WARNING: this will wipe out any existing info in the ~/.basecli dir -# including private keys, don't run if you have lots of local state already -basecli reset_all -basecli keys new cool -``` - -While we're at it let's setup a second account which we will use later in the tutorial - -``` -basecli keys new friend -``` - -Next we need to copy in the public address from our new key into the genesis block: - -``` -basecli keys get cool -o=json -vi ~/.basecoin/genesis.json --> cut/paste your pubkey from the results above -``` -or alternatively, without manual copy pasting: -``` -GENKEY=`basecli keys get cool -o json | jq .pubkey.data` -GENJSON=`cat ~/.basecoin/genesis.json` -echo $GENJSON | jq '.app_options.accounts[0].pub_key.data='$GENKEY > ~/.basecoin/genesis.json -``` - -Hurray! you are very rich and cool on this blockchain now. +If you like, you can manually add some more accounts to the blockchain by generating keys and editing the `~/.basecoin/genesis.json`. ## Start - Now we can start Basecoin: ``` @@ -74,22 +69,26 @@ You should see blocks start streaming in! ## Initialize Light-Client -Now that Basecoin is running we can initialize the light-client utility named -`basecli`. Basecli is used for sending transactions and querying the state. +Now that Basecoin is running we can initialize `basecli`, the light-client utility. +Basecli is used for sending transactions and querying the state. Leave Basecoin running and open a new terminal window. Here run: ``` basecli init --chain-id=test_chain_id --node=tcp://localhost:46657 ``` +Note it will ask you to verify the validator hash. For a blockchain on your local computer, don't worry about it. +If you're connecting to a blockchain over the internet, you should verify that the validator hash is correct. +This is so that all queries done with `basecli` can be cryptographically proven to be correct according to a known validator set. + ## Send transactions Now we are ready to send some transactions. First Let's check the balance of -the two accounts we setup earlier these two accounts: +the two accounts we setup earlier: ``` -ME=`basecli keys get cool -o=json | jq .address | tr -d '"'` -YOU=`basecli keys get friend -o=json | jq .address | tr -d '"'` +ME=$(basecli keys get cool | awk '{print $2}') +YOU=$(basecli keys get friend | awk '{print $2}') basecli query account $ME basecli query account $YOU ``` @@ -101,9 +100,6 @@ Let's send funds from the first account to the second: basecli tx send --name=cool --amount=1000mycoin --to=0x$YOU --sequence=1 ``` -By default, the CLI looks for a `key.json` to sign the transaction with. -To specify a different key, we can use the `--from` flag. - Now if we check the second account, it should have `1000` 'mycoin' coins! ``` @@ -124,21 +120,42 @@ If we try to send too much, we'll get an error: basecli tx send --name=friend --amount=500000mycoin --to=$ME --sequence=1 ``` -And if you want to see the original tx, as well as verifying that it -really is in the blockchain, look at the send response: +Let's send another transaction: ``` basecli tx send --name=cool --amount=2345mycoin --to=$YOU --sequence=2 -# TXHASH from the json output -basecli query tx $TXHASH +``` + +Note the `hash` value in the response - this is the hash of the transaction. +We can query for the transaction by this hash: + +``` +basecli query tx ``` See `basecli tx send --help` for additional details. -For a better understanding of the options, it helps to understand the +## Proof + +Even if you don't see it in the UI, the result of every query comes with a proof. +This is a Merkle proof that the result of the query is actually contained in the state. +and the state's Merkle root is contained in a recent block header. +Behind the scenes, `countercli` will not only verify that this state matches the header, +but also that the header is properly signed by the known validator set. +It will even update the validator set as needed, so long +as there have not been major changes and it is secure to do so. So, if you wonder +why the query may take a second... there is a lot of work going on in the +background to make sure even a lying full node can't trick your client. + +In a latter [guide on InterBlockchainCommunication](ibc.md), we'll use these +proofs to post transactions to other chains. + +## Accounts and Transactions + +For a better understanding of how to further use the tools, it helps to understand the underlying data structures. -## Accounts +### Accounts The Basecoin state consists entirely of a set of accounts. Each account contains a public key, a balance in many different coin denominations, and a @@ -162,6 +179,9 @@ type Coin struct { } ``` +If you want to add more coins to a blockchain, you can do so manually in the `~/.basecoin/genesis.json` before +you start the blockchain for the first time. + Accounts are serialized and stored in a Merkle tree under the key `base/a/
`, where `
` is the address of the account. Typically, the address of the account is the 20-byte `RIPEMD160` hash of the @@ -170,7 +190,7 @@ public key, but other formats are acceptable as well, as defined in the Merkle tree used in Basecoin is a balanced, binary search tree, which we call an [IAVL tree](https://github.com/tendermint/go-merkle). -## Transactions +### 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 @@ -229,9 +249,9 @@ transaction. ## Conclusion -In this guide, we introduced the `basecoin` tool, demonstrated how to use it to -send tokens between accounts, and discussed the underlying data types for -accounts and transactions, specifically the `Account` and the `SendTx`. In the -[next guide](basecoin-plugins.md), we introduce the Basecoin plugin system, +In this guide, we introduced the `basecoin` and `basecli` tools, +demonstrated how to start a new basecoin blockchain and how to send tokens between accounts, +and discussed the underlying data types for accounts and transactions, specifically the `Account` and the `SendTx`. +In the [next guide](basecoin-plugins.md), we introduce the Basecoin plugin system, which uses a new transaction type, the `AppTx`, to extend the functionality of the Basecoin system with arbitrary logic. diff --git a/docs/guide/basecoin-plugins.md b/docs/guide/basecoin-plugins.md index 5c2114d0cc..8bdee823ed 100644 --- a/docs/guide/basecoin-plugins.md +++ b/docs/guide/basecoin-plugins.md @@ -1,27 +1,32 @@ # Basecoin Plugins In the [previous guide](basecoin-basics.md), we saw how to use the `basecoin` -tool to start a blockchain and send transactions. We also learned about +tool to start a blockchain and the `basecli` tools to send transactions. We also learned about `Account` and `SendTx`, the basic data types giving us a multi-asset -cryptocurrency. Here, we will demonstrate how to extend the `basecoin` tool to -use another transaction type, the `AppTx`, to send data to a custom plugin. In -this example we explore a simple plugin name `counter`. +cryptocurrency. Here, we will demonstrate how to extend the tools to +use another transaction type, the `AppTx`, so we can send data to a custom plugin. In +this example we explore a simple plugin named `counter`. ## Example Plugin -The design of the `basecoin` tool makes it easy to extend for custom -functionality. The Counter plugin is bundled with basecoin, so if you have -already [installed basecoin](install.md) then you should be able to run a full -node with `counter` and the a light-client `countercli` from terminal. The -Counter plugin is just like the `basecoin` tool. They both use the same -library of commands, including one for signing and broadcasting `SendTx`. +The design of the `basecoin` and `basecli` tools makes it easy to extend for custom +functionality. We provide examples of such extensions in the basecoin repository under `docs/guide/counter`. +You can install them from the basecoin directory with: + +``` +`go install ./docs/guide/counter/cmd/... +``` + +This will give you both the `counter` and `countercli` binaries. +The former is just like `basecoin`, but with the counter plugin activated. +The latter is just like `basecli`, but with support for sending transactions to the counter plugin. Counter transactions take two custom inputs, a boolean argument named `valid`, and a coin amount named `countfee`. The transaction is only accepted if both `valid` is set to true and the transaction input coins is greater than `countfee` that the user provides. -A new blockchain can be initialized and started just like with in the [previous +A new blockchain can be initialized and started just like in the [previous guide](basecoin-basics.md): ``` @@ -29,16 +34,12 @@ guide](basecoin-basics.md): rm -rf ~/.counter countercli reset_all -counter init countercli keys new cool countercli keys new friend -GENKEY=`countercli keys get cool -o json | jq .pubkey.data` -GENJSON=`cat ~/.counter/genesis.json` -echo $GENJSON | jq '.app_options.accounts[0].pub_key.data='$GENKEY > ~/.counter/genesis.json +counter init $(countercli keys get cool | awk '{print $2}') counter start - ``` The default files are stored in `~/.counter`. In another window we can @@ -47,7 +48,7 @@ initialize the light-client and send a transaction: ``` countercli init --chain-id=test_chain_id --node=tcp://localhost:46657 -YOU=`countercli keys get friend -o=json | jq .address | tr -d '"'` +YOU=$(countercli keys get friend | awk '{print $2}') countercli tx send --name=cool --amount=1000mycoin --to=0x$YOU --sequence=1 ``` @@ -78,21 +79,12 @@ countercli tx counter --name cool --amount=2mycoin --sequence=4 --valid --countf countercli query counter ``` -The value Counter value should be 2, because we sent a second valid transaction. +The Counter value should be 2, because we sent a second valid transaction. And this time, since we sent a countfee (which must be less than or equal to the total amount sent with the tx), it stores the `TotalFees` on the counter as well. -Even if you don't see it in the UI, the result of the query comes with a proof. -This is a Merkle proof that the state is what we say it is, and ties that query -to a particular header. Behind the scenes, `countercli` will not only verify that -this state matches the header, but also that the header is properly signed by -the known validator set. It will even update the validator set as needed, so long -as there have not been major changes and it is secure to do so. So, if you wonder -why the query may take a second... there is a lot of work going on in the -background to make sure even a lying full node can't trick your client. - -In a latter [guide on InterBlockchainCommunication](ibc.md), we'll use these -proofs to post transactions to other chains. +Keep it mind that, just like with `basecli`, the `countercli` verifies a proof +that the query response is correct and up-to-date. Now, before we implement our own plugin and tooling, it helps to understand the `AppTx` and the design of the plugin system. @@ -178,12 +170,11 @@ alone, but you should change any occurrences of `counter` to whatever your plugin tool is going to be called. You must also register your plugin(s) with the basecoin app with `RegisterStartPlugin`. -The light-client which is located in `cmd/countercli/main.go` allows for is -where transaction and query commands are designated. Similarity this command -can be mostly left alone besides replacing the application name and adding -references to new plugin commands +The light-client is located in `cmd/countercli/main.go` and allows for +transaction and query commands. This file can also be left mostly alone besides replacing the application name and adding +references to new plugin commands. -Next is the custom commands in `cmd/countercli/commands/`. These files is +Next is the custom commands in `cmd/countercli/commands/`. These files are where we extend the tool with any new commands and flags we need to send transactions or queries to our plugin. You define custom `tx` and `query` subcommands, which are registered in `main.go` (avoiding `init()`