github.com/vipernet-xyz/tm@v0.34.24/docs/app-dev/getting-started.md (about)

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