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.

299 lines
7.6 KiB

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