doc revisit basecoin-basics.md

This commit is contained in:
rigel rozanski 2017-06-17 21:15:54 -04:00
parent a20b640f05
commit 7dad89b152
3 changed files with 111 additions and 64 deletions

View File

@ -115,7 +115,7 @@ git log | head -1
In the main repo (tendermint, basecoin, ...) where the binary will be built: In the main repo (tendermint, basecoin, ...) where the binary will be built:
``` ```
cd $GOPATH/src/github.com/tendermint/tendermin cd $GOPATH/src/github.com/tendermint/tendermint
git checkout master git checkout master
git pull git pull
# -> edit glide.lock, set the version of go-p2p (for example) # -> edit glide.lock, set the version of go-p2p (for example)

View File

@ -6,7 +6,7 @@ and what is happening under the hood.
## Install ## Install
Installing basecoin is simple: Installing Basecoin is simple:
``` ```
go get -u github.com/tendermint/basecoin/cmd/basecoin go get -u github.com/tendermint/basecoin/cmd/basecoin
@ -14,7 +14,7 @@ go get -u github.com/tendermint/basecoin/cmd/basecoin
If you have trouble, see the [installation guide](install.md). If you have trouble, see the [installation guide](install.md).
## Initialization ## Initialize Basecoin
To initialize a new Basecoin blockchain, run: To initialize a new Basecoin blockchain, run:
@ -22,12 +22,42 @@ To initialize a new Basecoin blockchain, run:
basecoin init basecoin init
``` ```
This will create the necessary files for a Basecoin blockchain with one validator and one account in `~/.basecoin`. This will create the necessary files for a Basecoin blockchain with one
For more options on setup, see the [guide to using the Basecoin tool](/docs/guide/basecoin-tool.md). validator and one account 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:
```
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.
## Start ## Start
Now we can start basecoin: Now we can start Basecoin:
``` ```
basecoin start basecoin start
@ -35,64 +65,71 @@ basecoin start
You should see blocks start streaming in! You should see blocks start streaming in!
## Send transactions ## Initialize Light-Client
Now we are ready to send some transactions. First, open another window. Now that Basecoin is running we can initialize the light-client utility named
If you take a look at the `~/.basecoin/genesis.json` file, you will see one account listed under the `app_options`. `basecli`. Basecli is used for sending transactions and querying the state.
This account corresponds to the private key in `~/.basecoin/key.json`. Leave Basecoin running and open a new terminal window. Here run:
We also included the private key for another account, in `~/.basecoin/key2.json`.
Leave basecoin running and open a new terminal window.
Let's check the balance of these two accounts:
``` ```
basecoin account 0x1B1BE55F969F54064628A63B9559E7C21C925165 basecli init --chain-id=test_chain_id --node=tcp://localhost:46657
basecoin account 0x1DA7C74F9C219229FD54CC9F7386D5A3839F0090 ```
## 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:
```
ME=`basecli keys get cool -o=json | jq .address | tr -d '"'`
YOU=`basecli keys get friend -o=json | jq .address | tr -d '"'`
basecli query account $ME
basecli query account $YOU
``` ```
The first account is flush with cash, while the second account doesn't exist. The first account is flush with cash, while the second account doesn't exist.
Let's send funds from the first account to the second: Let's send funds from the first account to the second:
``` ```
basecoin tx send --to 0x1DA7C74F9C219229FD54CC9F7386D5A3839F0090 --amount 10mycoin 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. 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. To specify a different key, we can use the `--from` flag.
Now if we check the second account, it should have `10` 'mycoin' coins! Now if we check the second account, it should have `1000` 'mycoin' coins!
``` ```
basecoin account 0x1DA7C74F9C219229FD54CC9F7386D5A3839F0090 basecli query account $YOU
``` ```
We can send some of these coins back like so: We can send some of these coins back like so:
``` ```
basecoin tx send --to 0x1B1BE55F969F54064628A63B9559E7C21C925165 --from key2.json --amount 5mycoin basecli tx send --name=friend --amount=500mycoin --to=0x$ME --sequence=1
``` ```
Note how we use the `--from` flag to select a different account to send from. Note how we use the `--name` flag to select a different account to send from.
If we try to send too much, we'll get an error: If we try to send too much, we'll get an error:
``` ```
basecoin tx send --to 0x1B1BE55F969F54064628A63B9559E7C21C925165 --from key2.json --amount 100mycoin basecli tx send --name=friend --amount=500000mycoin --to=0x$ME --sequence=1
``` ```
See `basecoin tx send --help` for additional details. See `basecli tx send --help` for additional details.
For a better understanding of the options, it helps to understand the underlying data structures. For a better understanding of the options, it helps to understand the
underlying data structures.
## Accounts ## Accounts
The Basecoin state consists entirely of a set of accounts. The Basecoin state consists entirely of a set of accounts. Each account
Each account contains a public key, contains a public key, a balance in many different coin denominations, and a
a balance in many different coin denominations, strictly increasing sequence number for replay protection. This type of
and a strictly increasing sequence number for replay protection. account was directly inspired by accounts in Ethereum, and is unlike Bitcoin's
This type of account was directly inspired by accounts in Ethereum, use of Unspent Transaction Outputs (UTXOs). Note Basecoin is a multi-asset
and is unlike Bitcoin's use of Unspent Transaction Outputs (UTXOs). cryptocurrency, so each account can have many different kinds of tokens.
Note Basecoin is a multi-asset cryptocurrency, so each account can have many different kinds of tokens.
```golang ```golang
type Account struct { type Account struct {
@ -109,17 +146,21 @@ type Coin struct {
} }
``` ```
Accounts are serialized and stored in a Merkle tree under the key `base/a/<address>`, where `<address>` is the address of the account. Accounts are serialized and stored in a Merkle tree under the key
Typically, the address of the account is the 20-byte `RIPEMD160` hash of the public key, but other formats are acceptable as well, `base/a/<address>`, where `<address>` is the address of the account.
as defined in the [Tendermint crypto library](https://github.com/tendermint/go-crypto). Typically, the address of the account is the 20-byte `RIPEMD160` hash of the
The Merkle tree used in Basecoin is a balanced, binary search tree, which we call an [IAVL tree](https://github.com/tendermint/go-merkle). public key, but other formats are acceptable as well, as defined in the
[Tendermint crypto library](https://github.com/tendermint/go-crypto). 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. Basecoin defines a simple transaction type, the `SendTx`, which allows tokens
The `SendTx` takes a list of inputs and a list of outputs, to be sent to other accounts. The `SendTx` takes a list of inputs and a list
and transfers all the tokens listed in the inputs from their corresponding accounts to the accounts listed in the output. of outputs, and transfers all the tokens listed in the inputs from their
The `SendTx` is structured as follows: corresponding accounts to the accounts listed in the output. The `SendTx` is
structured as follows:
```golang ```golang
type SendTx struct { type SendTx struct {
@ -143,32 +184,38 @@ type TxOutput struct {
} }
``` ```
Note the `SendTx` includes a field for `Gas` and `Fee`. Note the `SendTx` includes a field for `Gas` and `Fee`. The `Gas` limits the
The `Gas` limits the total amount of computation that can be done by the transaction, total amount of computation that can be done by the transaction, while the
while the `Fee` refers to the total amount paid in fees. `Fee` refers to the total amount paid in fees. This is slightly different from
This is slightly different from Ethereum's concept of `Gas` and `GasPrice`, Ethereum's concept of `Gas` and `GasPrice`, where `Fee = Gas x GasPrice`. In
where `Fee = Gas x GasPrice`. In Basecoin, the `Gas` and `Fee` are independent, Basecoin, the `Gas` and `Fee` are independent, and the `GasPrice` is implicit.
and the `GasPrice` is implicit.
In Basecoin, the `Fee` is meant to be used by the validators to inform the ordering In Basecoin, the `Fee` is meant to be used by the validators to inform the
of transactions, like in Bitcoin. And the `Gas` is meant to be used by the application ordering of transactions, like in Bitcoin. And the `Gas` is meant to be used
plugin to control its execution. There is currently no means to pass `Fee` information by the application plugin to control its execution. There is currently no
to the Tendermint validators, but it will come soon... means to pass `Fee` information to the Tendermint validators, but it will come
soon...
Note also that the `PubKey` only needs to be sent for `Sequence == 0`. Note also that the `PubKey` only needs to be sent for `Sequence == 0`. After
After that, it is stored under the account in the Merkle tree and subsequent transactions can exclude it, that, it is stored under the account in the Merkle tree and subsequent
using only the `Address` to refer to the sender. Ethereum does not require public keys to be sent in transactions transactions can exclude it, using only the `Address` to refer to the sender.
as it uses a different elliptic curve scheme which enables the public key to be derived from the signature itself. 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 derived from
the signature itself.
Finally, note that the use of multiple inputs and multiple outputs allows us to send many Finally, note that the use of multiple inputs and multiple outputs allows us to
different types of tokens between many different accounts at once in an atomic transaction. send many different types of tokens between many different accounts at once in
Thus, the `SendTx` can serve as a basic unit of decentralized exchange. When using multiple an atomic transaction. Thus, the `SendTx` can serve as a basic unit of
inputs and outputs, you must make sure that the sum of coins of the inputs equals the sum of decentralized exchange. When using multiple inputs and outputs, you must make
coins of the outputs (no creating money), and that all accounts that provide inputs have signed the transaction. 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.
## Conclusion ## Conclusion
In this guide, we introduced the `basecoin` tool, demonstrated how to use it to send tokens between accounts, In this guide, we introduced the `basecoin` tool, demonstrated how to use it to
and discussed the underlying data types for accounts and transactions, specifically the `Account` and the `SendTx`. send tokens between accounts, and discussed the underlying data types for
In the [next guide](basecoin-plugins.md), we introduce the basecoin plugin system, which uses a new transaction type, the `AppTx`, accounts and transactions, specifically the `Account` and the `SendTx`. In the
to extend the functionality of the Basecoin system with arbitrary logic. [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.

View File

@ -125,8 +125,8 @@ Now we can make a `genesis.json` file and add an account with our public key:
``` ```
Here we've granted ourselves `1000000000` units of the `gold` token. Here we've granted ourselves `1000000000` units of the `gold` token.
Note that we've also set the `chain_id` to be `example-chain`. Note that we've also set the `chain-id` to be `example-chain`.
All transactions must therefore include the `--chain_id example-chain` in order to make sure they are valid for this chain. All transactions must therefore include the `--chain-id example-chain` in order to make sure they are valid for this chain.
Previously, we didn't need this flag because we were using the default chain ID ("test_chain_id"). Previously, we didn't need this flag because we were using the default chain ID ("test_chain_id").
Now that we're using a custom chain, we need to specify the chain explicitly on the command line. Now that we're using a custom chain, we need to specify the chain explicitly on the command line.