From 20e1eadcf19af731c5f709b57b2e492c361fcf88 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 6 Jun 2018 09:16:53 -0400 Subject: [PATCH] getting started --- docs/getting-started.md | 265 +++++++++++++++++++++++++++++++ docs/getting-started.rst | 325 --------------------------------------- 2 files changed, 265 insertions(+), 325 deletions(-) create mode 100644 docs/getting-started.md delete mode 100644 docs/getting-started.rst diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 000000000..7ec3c062b --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,265 @@ +# Getting Started + +## First Tendermint App + +As a general purpose blockchain engine, Tendermint is agnostic to the +application you want to run. So, to run a complete blockchain that does +something useful, you must start two programs: one is Tendermint Core, +the other is your application, which can be written in any programming +language. Recall from [the intro to +ABCI](introduction.html#ABCI-Overview) that Tendermint Core handles all +the p2p and consensus stuff, and just forwards transactions to the +application when they need to be validated, or when they're ready to be +committed to a block. + +In this guide, we show you some examples of how to run an application +using Tendermint. + +### Install + +The first apps we will work with are written in Go. To install them, you +need to [install Go](https://golang.org/doc/install) and put +`$GOPATH/bin` in your `$PATH`; see +[here](https://github.com/tendermint/tendermint/wiki/Setting-GOPATH) for +more info. + +Then run + + go get -u github.com/tendermint/abci/cmd/abci-cli + +If there is an error, install and run the +[dep](https://github.com/golang/dep) tool to pin the dependencies: + + cd $GOPATH/src/github.com/tendermint/abci + make get_tools + make get_vendor_deps + make install + +Now you should have the `abci-cli` installed; you'll see a couple of +commands (`counter` and `kvstore`) that are example applications written +in Go. See below for an application written in JavaScript. + +Now, let's run some apps! + +## KVStore - A First Example + +The kvstore app is a [Merkle +tree](https://en.wikipedia.org/wiki/Merkle_tree) that just stores all +transactions. If the transaction contains an `=`, e.g. `key=value`, then +the `value` is stored under the `key` in the Merkle tree. Otherwise, the +full transaction bytes are stored as the key and the value. + +Let's start a kvstore application. + + abci-cli kvstore + +In another terminal, we can start Tendermint. If you have never run +Tendermint before, use: + + tendermint init + tendermint node + +If you have used Tendermint, you may want to reset the data for a new +blockchain by running `tendermint unsafe_reset_all`. Then you can run +`tendermint node` to start Tendermint, and connect to the app. For more +details, see [the guide on using Tendermint](./using-tendermint.html). + +You should see Tendermint making blocks! We can get the status of our +Tendermint node as follows: + + curl -s localhost:46657/status + +The `-s` just silences `curl`. For nicer output, pipe the result into a +tool like [jq](https://stedolan.github.io/jq/) or `json_pp`. + +Now let's send some transactions to the kvstore. + + curl -s 'localhost:46657/broadcast_tx_commit?tx="abcd"' + +Note the single quote (`'`) around the url, which ensures that the +double quotes (`"`) are not escaped by bash. This command sent a +transaction with bytes `abcd`, so `abcd` will be stored as both the key +and the value in the Merkle tree. The response should look something +like: + + { + "jsonrpc": "2.0", + "id": "", + "result": { + "check_tx": { + "fee": {} + }, + "deliver_tx": { + "tags": [ + { + "key": "YXBwLmNyZWF0b3I=", + "value": "amFl" + }, + { + "key": "YXBwLmtleQ==", + "value": "YWJjZA==" + } + ], + "fee": {} + }, + "hash": "9DF66553F98DE3C26E3C3317A3E4CED54F714E39", + "height": 14 + } + } + +We can confirm that our transaction worked and the value got stored by +querying the app: + + curl -s 'localhost:46657/abci_query?data="abcd"' + +The result should look like: + + { + "jsonrpc": "2.0", + "id": "", + "result": { + "response": { + "log": "exists", + "index": "-1", + "key": "YWJjZA==", + "value": "YWJjZA==" + } + } + } + +Note the `value` in the result (`YWJjZA==`); this is the base64-encoding +of the ASCII of `abcd`. You can verify this in a python 2 shell by +running `"61626364".decode('base64')` or in python 3 shell by running +`import codecs; codecs.decode("61626364", 'base64').decode('ascii')`. +Stay tuned for a future release that [makes this output more +human-readable](https://github.com/tendermint/abci/issues/32). + +Now let's try setting a different key and value: + + curl -s 'localhost:46657/broadcast_tx_commit?tx="name=satoshi"' + +Now if we query for `name`, we should get `satoshi`, or `c2F0b3NoaQ==` +in base64: + + curl -s 'localhost:46657/abci_query?data="name"' + +Try some other transactions and queries to make sure everything is +working! + +## Counter - Another Example + +Now that we've got the hang of it, let's try another application, the +`counter` app. + +The counter app doesn't use a Merkle tree, it just counts how many times +we've sent a transaction, or committed the state. + +This application has two modes: `serial=off` and `serial=on`. + +When `serial=on`, transactions must be a big-endian encoded incrementing +integer, starting at 0. + +If `serial=off`, there are no restrictions on transactions. + +In a live blockchain, transactions collect in memory before they are +committed into blocks. To avoid wasting resources on invalid +transactions, ABCI provides the `CheckTx` message, which application +developers can use to accept or reject transactions, before they are +stored in memory or gossipped to other peers. + +In this instance of the counter app, with `serial=on`, `CheckTx` only +allows transactions whose integer is greater than the last committed +one. + +Let's kill the previous instance of `tendermint` and the `kvstore` +application, and start the counter app. We can enable `serial=on` with a +flag: + + abci-cli counter --serial + +In another window, reset then start Tendermint: + + tendermint unsafe_reset_all + tendermint node + +Once again, you can see the blocks streaming by. Let's send some +transactions. Since we have set `serial=on`, the first transaction must +be the number `0`: + + curl localhost:46657/broadcast_tx_commit?tx=0x00 + +Note the empty (hence successful) response. The next transaction must be +the number `1`. If instead, we try to send a `5`, we get an error: + + > curl localhost:46657/broadcast_tx_commit?tx=0x05 + { + "jsonrpc": "2.0", + "id": "", + "result": { + "check_tx": { + "fee": {} + }, + "deliver_tx": { + "code": 2, + "log": "Invalid nonce. Expected 1, got 5", + "fee": {} + }, + "hash": "33B93DFF98749B0D6996A70F64071347060DC19C", + "height": 34 + } + } + +But if we send a `1`, it works again: + + > curl localhost:46657/broadcast_tx_commit?tx=0x01 + { + "jsonrpc": "2.0", + "id": "", + "result": { + "check_tx": { + "fee": {} + }, + "deliver_tx": { + "fee": {} + }, + "hash": "F17854A977F6FA7EEA1BD758E296710B86F72F3D", + "height": 60 + } + } + +For more details on the `broadcast_tx` API, see [the guide on using +Tendermint](./using-tendermint.html). + +## CounterJS - Example in Another Language + +We also want to run applications in another language - in this case, +we'll run a Javascript version of the `counter`. To run it, you'll need +to [install node](https://nodejs.org/en/download/). + +You'll also need to fetch the relevant repository, from +[here](https://github.com/tendermint/js-abci) then install it. As go +devs, we keep all our code under the `$GOPATH`, so run: + + go get github.com/tendermint/js-abci &> /dev/null + cd $GOPATH/src/github.com/tendermint/js-abci/example + npm install + cd .. + +Kill the previous `counter` and `tendermint` processes. Now run the app: + + node example/app.js + +In another window, reset and start `tendermint`: + + tendermint unsafe_reset_all + tendermint node + +Once again, you should see blocks streaming by - but now, our +application is written in javascript! Try sending some transactions, and +like before - the results should be the same: + + curl localhost:46657/broadcast_tx_commit?tx=0x00 # ok + curl localhost:46657/broadcast_tx_commit?tx=0x05 # invalid nonce + curl localhost:46657/broadcast_tx_commit?tx=0x01 # ok + +Neat, eh? diff --git a/docs/getting-started.rst b/docs/getting-started.rst deleted file mode 100644 index 9c722f0f1..000000000 --- a/docs/getting-started.rst +++ /dev/null @@ -1,325 +0,0 @@ -First Tendermint App -==================== - -As a general purpose blockchain engine, Tendermint is agnostic to the -application you want to run. So, to run a complete blockchain that does -something useful, you must start two programs: one is Tendermint Core, -the other is your application, which can be written in any programming -language. Recall from `the intro to ABCI `__ that -Tendermint Core handles all the p2p and consensus stuff, and just -forwards transactions to the application when they need to be validated, -or when they're ready to be committed to a block. - -In this guide, we show you some examples of how to run an application -using Tendermint. - -Install -------- - -The first apps we will work with are written in Go. To install them, you -need to `install Go `__ and put -``$GOPATH/bin`` in your -``$PATH``; see `here `__ for more info. - -Then run - -:: - - go get -u github.com/tendermint/abci/cmd/abci-cli - -If there is an error, install and run the `dep `__ tool to pin the -dependencies: - -:: - - cd $GOPATH/src/github.com/tendermint/abci - make get_tools - make get_vendor_deps - make install - -Now you should have the ``abci-cli`` installed; you'll see -a couple of commands (``counter`` and ``kvstore``) that are -example applications written in Go. See below for an application -written in JavaScript. - -Now, let's run some apps! - -KVStore - A First Example -------------------------- - -The kvstore app is a `Merkle -tree `__ that just stores all -transactions. If the transaction contains an ``=``, e.g. ``key=value``, -then the ``value`` is stored under the ``key`` in the Merkle tree. -Otherwise, the full transaction bytes are stored as the key and the -value. - -Let's start a kvstore application. - -:: - - abci-cli kvstore - -In another terminal, we can start Tendermint. If you have never run -Tendermint before, use: - -:: - - tendermint init - tendermint node - -If you have used Tendermint, you may want to reset the data for a new -blockchain by running ``tendermint unsafe_reset_all``. Then you can run -``tendermint node`` to start Tendermint, and connect to the app. For -more details, see `the guide on using -Tendermint <./using-tendermint.html>`__. - -You should see Tendermint making blocks! We can get the status of our -Tendermint node as follows: - -:: - - curl -s localhost:46657/status - -The ``-s`` just silences ``curl``. For nicer output, pipe the result into a -tool like `jq `__ or ``json_pp``. - -Now let's send some transactions to the kvstore. - -:: - - curl -s 'localhost:46657/broadcast_tx_commit?tx="abcd"' - -Note the single quote (``'``) around the url, which ensures that the -double quotes (``"``) are not escaped by bash. This command sent a -transaction with bytes ``abcd``, so ``abcd`` will be stored as both the -key and the value in the Merkle tree. The response should look something -like: - -:: - - { - "jsonrpc": "2.0", - "id": "", - "result": { - "check_tx": { - "fee": {} - }, - "deliver_tx": { - "tags": [ - { - "key": "YXBwLmNyZWF0b3I=", - "value": "amFl" - }, - { - "key": "YXBwLmtleQ==", - "value": "YWJjZA==" - } - ], - "fee": {} - }, - "hash": "9DF66553F98DE3C26E3C3317A3E4CED54F714E39", - "height": 14 - } - } - -We can confirm that our transaction worked and the value got stored by -querying the app: - -:: - - curl -s 'localhost:46657/abci_query?data="abcd"' - -The result should look like: - -:: - - { - "jsonrpc": "2.0", - "id": "", - "result": { - "response": { - "log": "exists", - "index": "-1", - "key": "YWJjZA==", - "value": "YWJjZA==" - } - } - } - -Note the ``value`` in the result (``YWJjZA==``); this is the -base64-encoding of the ASCII of ``abcd``. You can verify this in -a python 2 shell by running ``"61626364".decode('base64')`` or in python 3 shell by running ``import codecs; codecs.decode("61626364", 'base64').decode('ascii')``. Stay -tuned for a future release that `makes this output more human-readable `__. - -Now let's try setting a different key and value: - -:: - - curl -s 'localhost:46657/broadcast_tx_commit?tx="name=satoshi"' - -Now if we query for ``name``, we should get ``satoshi``, or -``c2F0b3NoaQ==`` in base64: - -:: - - curl -s 'localhost:46657/abci_query?data="name"' - -Try some other transactions and queries to make sure everything is -working! - -Counter - Another Example -------------------------- - -Now that we've got the hang of it, let's try another application, the -**counter** app. - -The counter app doesn't use a Merkle tree, it just counts how many times -we've sent a transaction, or committed the state. - -This application has two modes: ``serial=off`` and ``serial=on``. - -When ``serial=on``, transactions must be a big-endian encoded -incrementing integer, starting at 0. - -If ``serial=off``, there are no restrictions on transactions. - -In a live blockchain, transactions collect in memory before they are -committed into blocks. To avoid wasting resources on invalid -transactions, ABCI provides the ``CheckTx`` message, which application -developers can use to accept or reject transactions, before they are -stored in memory or gossipped to other peers. - -In this instance of the counter app, with ``serial=on``, ``CheckTx`` -only allows transactions whose integer is greater than the last -committed one. - -Let's kill the previous instance of ``tendermint`` and the ``kvstore`` -application, and start the counter app. We can enable ``serial=on`` with -a flag: - -:: - - abci-cli counter --serial - -In another window, reset then start Tendermint: - -:: - - tendermint unsafe_reset_all - tendermint node - -Once again, you can see the blocks streaming by. Let's send some -transactions. Since we have set ``serial=on``, the first transaction -must be the number ``0``: - -:: - - curl localhost:46657/broadcast_tx_commit?tx=0x00 - -Note the empty (hence successful) response. The next transaction must be -the number ``1``. If instead, we try to send a ``5``, we get an error: - -:: - - > curl localhost:46657/broadcast_tx_commit?tx=0x05 - { - "jsonrpc": "2.0", - "id": "", - "result": { - "check_tx": { - "fee": {} - }, - "deliver_tx": { - "code": 2, - "log": "Invalid nonce. Expected 1, got 5", - "fee": {} - }, - "hash": "33B93DFF98749B0D6996A70F64071347060DC19C", - "height": 34 - } - } - -But if we send a ``1``, it works again: - -:: - - > curl localhost:46657/broadcast_tx_commit?tx=0x01 - { - "jsonrpc": "2.0", - "id": "", - "result": { - "check_tx": { - "fee": {} - }, - "deliver_tx": { - "fee": {} - }, - "hash": "F17854A977F6FA7EEA1BD758E296710B86F72F3D", - "height": 60 - } - } - -For more details on the ``broadcast_tx`` API, see `the guide on using -Tendermint <./using-tendermint.html>`__. - -CounterJS - Example in Another Language ---------------------------------------- - -We also want to run applications in another language - in this case, -we'll run a Javascript version of the ``counter``. To run it, you'll -need to `install node `__. - -You'll also need to fetch the relevant repository, from `here `__ then install it. As go devs, we -keep all our code under the ``$GOPATH``, so run: - -:: - - go get github.com/tendermint/js-abci &> /dev/null - cd $GOPATH/src/github.com/tendermint/js-abci/example - npm install - cd .. - -Kill the previous ``counter`` and ``tendermint`` processes. Now run the -app: - -:: - - node example/app.js - -In another window, reset and start ``tendermint``: - -:: - - tendermint unsafe_reset_all - tendermint node - -Once again, you should see blocks streaming by - but now, our -application is written in javascript! Try sending some transactions, and -like before - the results should be the same: - -:: - - curl localhost:46657/broadcast_tx_commit?tx=0x00 # ok - curl localhost:46657/broadcast_tx_commit?tx=0x05 # invalid nonce - curl localhost:46657/broadcast_tx_commit?tx=0x01 # ok - -Neat, eh? - -Basecoin - A More Interesting Example -------------------------------------- - -We saved the best for last; the `Cosmos SDK `__ is a general purpose framework for building cryptocurrencies. Unlike the ``kvstore`` and ``counter``, which are strictly for example purposes. The reference implementation of Cosmos SDK is ``basecoin``, which demonstrates how to use the building blocks of the Cosmos SDK. - -The default ``basecoin`` application is a multi-asset cryptocurrency -that supports inter-blockchain communication (IBC). For more details on how -basecoin works and how to use it, see our `basecoin -guide `__ - -In this tutorial you learned how to run applications using Tendermint -on a single node. You saw how applications could be written in different -languages, and how to send transactions and query for the latest state. -But the true power of Tendermint comes from its ability to securely and -efficiently run an application across a distributed network of nodes, -while keeping them all in sync using its state-of-the-art consensus -protocol. Next, we show you how to deploy Tendermint testnets.