diff --git a/docs/basecoin/basics.rst b/docs/basecoin/basics.rst new file mode 100644 index 0000000000..4bb197897d --- /dev/null +++ b/docs/basecoin/basics.rst @@ -0,0 +1,321 @@ +Basecoin Basics +=============== + +Here we explain how to get started with a basic Basecoin blockchain, how +to send transactions between accounts using the ``basecoin`` tool, and +what is happening under the hood. + +Install +------- + +With go, it's one command: + +.. code:: shelldown[0] + +:: + + go get -u github.com/cosmos/cosmos-sdk + +If you have trouble, see the `installation guide <./install.html>`__. + +TODO: update all the below + +Generate some keys +~~~~~~~~~~~~~~~~~~ + +Let's generate two keys, one to receive an initial allocation of coins, +and one to send some coins to later: + +.. code:: shelldown[1] + +:: + + 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: + +.. code:: shelldown[2] + +:: + + basecoin init
+ +If you prefer not to copy-paste, you can provide the address +programatically: + +.. code:: shelldown[3] + +:: + + 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 (corresponding to your key) in +``~/.basecoin``. For more options on setup, see the `guide to using the +Basecoin tool `__. + +If you like, you can manually add some more accounts to the blockchain +by generating keys and editing the ``~/.basecoin/genesis.json``. + +Start Basecoin +~~~~~~~~~~~~~~ + +Now we can start Basecoin: + +.. code:: shelldown[4] + +:: + + basecoin start + +You should see blocks start streaming in! + +Initialize Light-Client +----------------------- + +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: + +.. code:: shelldown[5] + +:: + + basecli init --node=tcp://localhost:46657 --genesis=$HOME/.basecoin/genesis.json + +If you provide the genesis file to basecli, it can calculate the proper +chainID and validator hash. Basecli needs to get this information from +some trusted source, so all queries done with ``basecli`` can be +cryptographically proven to be correct according to a known validator +set. + +Note: that ``--genesis`` only works if there have been no validator set +changes since genesis. If there are validator set changes, you need to +find the current set through some other method. + +Send transactions +~~~~~~~~~~~~~~~~~ + +Now we are ready to send some transactions. First Let's check the +balance of the two accounts we setup earlier: + +.. code:: shelldown[6] + +:: + + ME=$(basecli keys get cool | awk '{print $2}') + YOU=$(basecli keys get friend | awk '{print $2}') + basecli query account $ME + basecli query account $YOU + +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: + +.. code:: shelldown[7] + +:: + + basecli tx send --name=cool --amount=1000mycoin --to=$YOU --sequence=1 + +Now if we check the second account, it should have ``1000`` 'mycoin' +coins! + +.. code:: shelldown[8] + +:: + + basecli query account $YOU + +We can send some of these coins back like so: + +.. code:: shelldown[9] + +:: + + basecli tx send --name=friend --amount=500mycoin --to=$ME --sequence=1 + +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: + +.. code:: shelldown[10] + +:: + + basecli tx send --name=friend --amount=500000mycoin --to=$ME --sequence=2 + +Let's send another transaction: + +.. code:: shelldown[11] + +:: + + basecli tx send --name=cool --amount=2345mycoin --to=$YOU --sequence=2 + +Note the ``hash`` value in the response - this is the hash of the +transaction. We can query for the transaction by this hash: + +.. code:: shelldown[12] + +:: + + basecli query tx + +See ``basecli tx send --help`` for additional details. + +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. + +Accounts and Transactions +------------------------- + +For a better understanding of how to further use the tools, it helps to +understand the underlying data structures. + +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 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. + +.. code:: golang + +:: + + type Account struct { + PubKey crypto.PubKey `json:"pub_key"` // May be nil, if not known. + Sequence int `json:"sequence"` + Balance Coins `json:"coins"` + } + + type Coins []Coin + + type Coin struct { + Denom string `json:"denom"` + Amount int64 `json:"amount"` + } + +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 public key, but other formats are acceptable as well, as defined +in the `Tendermint crypto +library `__. The Merkle tree +used in Basecoin is a balanced, binary search tree, which we call an +`IAVL tree `__. + +Transactions +~~~~~~~~~~~~ + +Basecoin defines a 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: + +.. code:: golang + +:: + + 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"` // + } + +Note 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. + +In Basecoin, 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... + +Note also 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 derived 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. 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. + +Clean Up +-------- + +**WARNING:** Running these commands will wipe out any existing +information in both the ``~/.basecli`` and ``~/.basecoin`` directories, +including private keys. + +To remove all the files created and refresh your environment (e.g., if +starting this tutorial again or trying something new), the following +commands are run: + +.. code:: shelldown[end-of-tutorials] + +:: + + basecli reset_all + rm -rf ~/.basecoin + +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``. diff --git a/docs/glossary.rst b/docs/glossary.rst index 165b6a74bd..bef1b7cdcf 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -255,42 +255,3 @@ signing, one could also specify the scope(s) that this signature authorizes. The `oauth protocol `__ also has to deal with a similar problem, and maybe could provide some inspiration. - -Replay Protection ------------------ - -In order to prevent `replay -attacks `__ 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. - -.. code:: 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 the SDK 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. diff --git a/docs/index.rst b/docs/index.rst index 911b4297f5..da7ca3c6eb 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -27,7 +27,16 @@ Basecoin :maxdepth: 2 basecoin/basics.rst - basecoin/plugins.rst + basecoin/extensions.rst + +Extensions +---------- + +.. toctree:: + :maxdepth: 2 + + x/replay-protection.rst + Staking Module -------------- diff --git a/docs/x/replay-protection.rst b/docs/x/replay-protection.rst new file mode 100644 index 0000000000..d262add974 --- /dev/null +++ b/docs/x/replay-protection.rst @@ -0,0 +1,38 @@ +Replay Protection +----------------- + +In order to prevent `replay +attacks `__ 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. + +.. code:: 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 the SDK 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.