You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

325 lines
9.4 KiB

6 years ago
6 years ago
  1. First Tendermint App
  2. ====================
  3. As a general purpose blockchain engine, Tendermint is agnostic to the
  4. application you want to run. So, to run a complete blockchain that does
  5. something useful, you must start two programs: one is Tendermint Core,
  6. the other is your application, which can be written in any programming
  7. language. Recall from `the intro to ABCI <introduction.html#ABCI-Overview>`__ that
  8. Tendermint Core handles all the p2p and consensus stuff, and just
  9. forwards transactions to the application when they need to be validated,
  10. or when they're ready to be committed to a block.
  11. In this guide, we show you some examples of how to run an application
  12. using Tendermint.
  13. Install
  14. -------
  15. The first apps we will work with are written in Go. To install them, you
  16. need to `install Go <https://golang.org/doc/install>`__ and put
  17. ``$GOPATH/bin`` in your
  18. ``$PATH``; see `here <https://github.com/tendermint/tendermint/wiki/Setting-GOPATH>`__ for more info.
  19. Then run
  20. ::
  21. go get -u github.com/tendermint/abci/cmd/abci-cli
  22. If there is an error, install and run the `dep <https://github.com/golang/dep>`__ tool to pin the
  23. dependencies:
  24. ::
  25. cd $GOPATH/src/github.com/tendermint/abci
  26. make get_tools
  27. make get_vendor_deps
  28. make install
  29. Now you should have the ``abci-cli`` installed; you'll see
  30. a couple of commands (``counter`` and ``kvstore``) that are
  31. example applications written in Go. See below for an application
  32. written in JavaScript.
  33. Now, let's run some apps!
  34. KVStore - A First Example
  35. -------------------------
  36. The kvstore app is a `Merkle
  37. tree <https://en.wikipedia.org/wiki/Merkle_tree>`__ that just stores all
  38. transactions. If the transaction contains an ``=``, e.g. ``key=value``,
  39. then the ``value`` is stored under the ``key`` in the Merkle tree.
  40. Otherwise, the full transaction bytes are stored as the key and the
  41. value.
  42. Let's start a kvstore application.
  43. ::
  44. abci-cli kvstore
  45. In another terminal, we can start Tendermint. If you have never run
  46. Tendermint before, use:
  47. ::
  48. tendermint init
  49. tendermint node
  50. If you have used Tendermint, you may want to reset the data for a new
  51. blockchain by running ``tendermint unsafe_reset_all``. Then you can run
  52. ``tendermint node`` to start Tendermint, and connect to the app. For
  53. more details, see `the guide on using
  54. Tendermint <./using-tendermint.html>`__.
  55. You should see Tendermint making blocks! We can get the status of our
  56. Tendermint node as follows:
  57. ::
  58. curl -s localhost:46657/status
  59. The ``-s`` just silences ``curl``. For nicer output, pipe the result into a
  60. tool like `jq <https://stedolan.github.io/jq/>`__ or ``json_pp``.
  61. Now let's send some transactions to the kvstore.
  62. ::
  63. curl -s 'localhost:46657/broadcast_tx_commit?tx="abcd"'
  64. Note the single quote (``'``) around the url, which ensures that the
  65. double quotes (``"``) are not escaped by bash. This command sent a
  66. transaction with bytes ``abcd``, so ``abcd`` will be stored as both the
  67. key and the value in the Merkle tree. The response should look something
  68. like:
  69. ::
  70. {
  71. "jsonrpc": "2.0",
  72. "id": "",
  73. "result": {
  74. "check_tx": {
  75. "fee": {}
  76. },
  77. "deliver_tx": {
  78. "tags": [
  79. {
  80. "key": "YXBwLmNyZWF0b3I=",
  81. "value": "amFl"
  82. },
  83. {
  84. "key": "YXBwLmtleQ==",
  85. "value": "YWJjZA=="
  86. }
  87. ],
  88. "fee": {}
  89. },
  90. "hash": "9DF66553F98DE3C26E3C3317A3E4CED54F714E39",
  91. "height": 14
  92. }
  93. }
  94. We can confirm that our transaction worked and the value got stored by
  95. querying the app:
  96. ::
  97. curl -s 'localhost:46657/abci_query?data="abcd"'
  98. The result should look like:
  99. ::
  100. {
  101. "jsonrpc": "2.0",
  102. "id": "",
  103. "result": {
  104. "response": {
  105. "log": "exists",
  106. "index": "-1",
  107. "key": "YWJjZA==",
  108. "value": "YWJjZA=="
  109. }
  110. }
  111. }
  112. Note the ``value`` in the result (``YWJjZA==``); this is the
  113. base64-encoding of the ASCII of ``abcd``. You can verify this in
  114. 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
  115. tuned for a future release that `makes this output more human-readable <https://github.com/tendermint/abci/issues/32>`__.
  116. Now let's try setting a different key and value:
  117. ::
  118. curl -s 'localhost:46657/broadcast_tx_commit?tx="name=satoshi"'
  119. Now if we query for ``name``, we should get ``satoshi``, or
  120. ``c2F0b3NoaQ==`` in base64:
  121. ::
  122. curl -s 'localhost:46657/abci_query?data="name"'
  123. Try some other transactions and queries to make sure everything is
  124. working!
  125. Counter - Another Example
  126. -------------------------
  127. Now that we've got the hang of it, let's try another application, the
  128. **counter** app.
  129. The counter app doesn't use a Merkle tree, it just counts how many times
  130. we've sent a transaction, or committed the state.
  131. This application has two modes: ``serial=off`` and ``serial=on``.
  132. When ``serial=on``, transactions must be a big-endian encoded
  133. incrementing integer, starting at 0.
  134. If ``serial=off``, there are no restrictions on transactions.
  135. In a live blockchain, transactions collect in memory before they are
  136. committed into blocks. To avoid wasting resources on invalid
  137. transactions, ABCI provides the ``CheckTx`` message, which application
  138. developers can use to accept or reject transactions, before they are
  139. stored in memory or gossipped to other peers.
  140. In this instance of the counter app, with ``serial=on``, ``CheckTx``
  141. only allows transactions whose integer is greater than the last
  142. committed one.
  143. Let's kill the previous instance of ``tendermint`` and the ``kvstore``
  144. application, and start the counter app. We can enable ``serial=on`` with
  145. a flag:
  146. ::
  147. abci-cli counter --serial
  148. In another window, reset then start Tendermint:
  149. ::
  150. tendermint unsafe_reset_all
  151. tendermint node
  152. Once again, you can see the blocks streaming by. Let's send some
  153. transactions. Since we have set ``serial=on``, the first transaction
  154. must be the number ``0``:
  155. ::
  156. curl localhost:46657/broadcast_tx_commit?tx=0x00
  157. Note the empty (hence successful) response. The next transaction must be
  158. the number ``1``. If instead, we try to send a ``5``, we get an error:
  159. ::
  160. > curl localhost:46657/broadcast_tx_commit?tx=0x05
  161. {
  162. "jsonrpc": "2.0",
  163. "id": "",
  164. "result": {
  165. "check_tx": {
  166. "fee": {}
  167. },
  168. "deliver_tx": {
  169. "code": 2,
  170. "log": "Invalid nonce. Expected 1, got 5",
  171. "fee": {}
  172. },
  173. "hash": "33B93DFF98749B0D6996A70F64071347060DC19C",
  174. "height": 34
  175. }
  176. }
  177. But if we send a ``1``, it works again:
  178. ::
  179. > curl localhost:46657/broadcast_tx_commit?tx=0x01
  180. {
  181. "jsonrpc": "2.0",
  182. "id": "",
  183. "result": {
  184. "check_tx": {
  185. "fee": {}
  186. },
  187. "deliver_tx": {
  188. "fee": {}
  189. },
  190. "hash": "F17854A977F6FA7EEA1BD758E296710B86F72F3D",
  191. "height": 60
  192. }
  193. }
  194. For more details on the ``broadcast_tx`` API, see `the guide on using
  195. Tendermint <./using-tendermint.html>`__.
  196. CounterJS - Example in Another Language
  197. ---------------------------------------
  198. We also want to run applications in another language - in this case,
  199. we'll run a Javascript version of the ``counter``. To run it, you'll
  200. need to `install node <https://nodejs.org/en/download/>`__.
  201. You'll also need to fetch the relevant repository, from `here <https://github.com/tendermint/js-abci>`__ then install it. As go devs, we
  202. keep all our code under the ``$GOPATH``, so run:
  203. ::
  204. go get github.com/tendermint/js-abci &> /dev/null
  205. cd $GOPATH/src/github.com/tendermint/js-abci/example
  206. npm install
  207. cd ..
  208. Kill the previous ``counter`` and ``tendermint`` processes. Now run the
  209. app:
  210. ::
  211. node example/app.js
  212. In another window, reset and start ``tendermint``:
  213. ::
  214. tendermint unsafe_reset_all
  215. tendermint node
  216. Once again, you should see blocks streaming by - but now, our
  217. application is written in javascript! Try sending some transactions, and
  218. like before - the results should be the same:
  219. ::
  220. curl localhost:46657/broadcast_tx_commit?tx=0x00 # ok
  221. curl localhost:46657/broadcast_tx_commit?tx=0x05 # invalid nonce
  222. curl localhost:46657/broadcast_tx_commit?tx=0x01 # ok
  223. Neat, eh?
  224. Basecoin - A More Interesting Example
  225. -------------------------------------
  226. We saved the best for last; the `Cosmos SDK <https://github.com/cosmos/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.
  227. The default ``basecoin`` application is a multi-asset cryptocurrency
  228. that supports inter-blockchain communication (IBC). For more details on how
  229. basecoin works and how to use it, see our `basecoin
  230. guide <http://cosmos-sdk.readthedocs.io/en/latest/basecoin-basics.html>`__
  231. In this tutorial you learned how to run applications using Tendermint
  232. on a single node. You saw how applications could be written in different
  233. languages, and how to send transactions and query for the latest state.
  234. But the true power of Tendermint comes from its ability to securely and
  235. efficiently run an application across a distributed network of nodes,
  236. while keeping them all in sync using its state-of-the-art consensus
  237. protocol. Next, we show you how to deploy Tendermint testnets.