github.com/vipernet-xyz/tendermint-core@v0.32.0/docs/app-dev/abci-cli.md (about)

     1  ---
     2  order: 2
     3  ---
     4  
     5  # Using ABCI-CLI
     6  
     7  To facilitate testing and debugging of ABCI servers and simple apps, we
     8  built a CLI, the `abci-cli`, for sending ABCI messages from the command
     9  line.
    10  
    11  ## Install
    12  
    13  Make sure you [have Go installed](https://golang.org/doc/install).
    14  
    15  Next, install the `abci-cli` tool and example applications:
    16  
    17  ```
    18  mkdir -p $GOPATH/src/github.com/tendermint
    19  cd $GOPATH/src/github.com/tendermint
    20  git clone https://github.com/tendermint/tendermint.git
    21  cd tendermint
    22  make tools
    23  make install_abci
    24  ```
    25  
    26  Now run `abci-cli` to see the list of commands:
    27  
    28  ```
    29  Usage:
    30    abci-cli [command]
    31  
    32  Available Commands:
    33    batch       Run a batch of abci commands against an application
    34    check_tx    Validate a tx
    35    commit      Commit the application state and return the Merkle root hash
    36    console     Start an interactive abci console for multiple commands
    37    counter     ABCI demo example
    38    deliver_tx  Deliver a new tx to the application
    39    kvstore     ABCI demo example
    40    echo        Have the application echo a message
    41    help        Help about any command
    42    info        Get some info about the application
    43    query       Query the application state
    44    set_option  Set an options on the application
    45  
    46  Flags:
    47        --abci string      socket or grpc (default "socket")
    48        --address string   address of application socket (default "tcp://127.0.0.1:26658")
    49    -h, --help             help for abci-cli
    50    -v, --verbose          print the command and results as if it were a console session
    51  
    52  Use "abci-cli [command] --help" for more information about a command.
    53  ```
    54  
    55  ## KVStore - First Example
    56  
    57  The `abci-cli` tool lets us send ABCI messages to our application, to
    58  help build and debug them.
    59  
    60  The most important messages are `deliver_tx`, `check_tx`, and `commit`,
    61  but there are others for convenience, configuration, and information
    62  purposes.
    63  
    64  We'll start a kvstore application, which was installed at the same time
    65  as `abci-cli` above. The kvstore just stores transactions in a merkle
    66  tree.
    67  
    68  Its code can be found
    69  [here](https://github.com/tendermint/tendermint/blob/master/abci/cmd/abci-cli/abci-cli.go)
    70  and looks like:
    71  
    72  ```
    73  func cmdKVStore(cmd *cobra.Command, args []string) error {
    74      logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
    75  
    76      // Create the application - in memory or persisted to disk
    77      var app types.Application
    78      if flagPersist == "" {
    79          app = kvstore.NewKVStoreApplication()
    80      } else {
    81          app = kvstore.NewPersistentKVStoreApplication(flagPersist)
    82          app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore"))
    83      }
    84  
    85      // Start the listener
    86      srv, err := server.NewServer(flagAddrD, flagAbci, app)
    87      if err != nil {
    88          return err
    89      }
    90      srv.SetLogger(logger.With("module", "abci-server"))
    91      if err := srv.Start(); err != nil {
    92          return err
    93      }
    94  
    95      // Stop upon receiving SIGTERM or CTRL-C.
    96      tmos.TrapSignal(logger, func() {
    97          // Cleanup
    98          srv.Stop()
    99      })
   100  
   101      // Run forever.
   102      select {}
   103  }
   104  ```
   105  
   106  Start by running:
   107  
   108  ```
   109  abci-cli kvstore
   110  ```
   111  
   112  And in another terminal, run
   113  
   114  ```
   115  abci-cli echo hello
   116  abci-cli info
   117  ```
   118  
   119  You'll see something like:
   120  
   121  ```
   122  -> data: hello
   123  -> data.hex: 68656C6C6F
   124  ```
   125  
   126  and:
   127  
   128  ```
   129  -> data: {"size":0}
   130  -> data.hex: 7B2273697A65223A307D
   131  ```
   132  
   133  An ABCI application must provide two things:
   134  
   135  - a socket server
   136  - a handler for ABCI messages
   137  
   138  When we run the `abci-cli` tool we open a new connection to the
   139  application's socket server, send the given ABCI message, and wait for a
   140  response.
   141  
   142  The server may be generic for a particular language, and we provide a
   143  [reference implementation in
   144  Golang](https://github.com/tendermint/tendermint/tree/master/abci/server). See the
   145  [list of other ABCI implementations](https://github.com/tendermint/awesome#ecosystem) for servers in
   146  other languages.
   147  
   148  The handler is specific to the application, and may be arbitrary, so
   149  long as it is deterministic and conforms to the ABCI interface
   150  specification.
   151  
   152  So when we run `abci-cli info`, we open a new connection to the ABCI
   153  server, which calls the `Info()` method on the application, which tells
   154  us the number of transactions in our Merkle tree.
   155  
   156  Now, since every command opens a new connection, we provide the
   157  `abci-cli console` and `abci-cli batch` commands, to allow multiple ABCI
   158  messages to be sent over a single connection.
   159  
   160  Running `abci-cli console` should drop you in an interactive console for
   161  speaking ABCI messages to your application.
   162  
   163  Try running these commands:
   164  
   165  ```
   166  > echo hello
   167  -> code: OK
   168  -> data: hello
   169  -> data.hex: 0x68656C6C6F
   170  
   171  > info
   172  -> code: OK
   173  -> data: {"size":0}
   174  -> data.hex: 0x7B2273697A65223A307D
   175  
   176  > commit
   177  -> code: OK
   178  -> data.hex: 0x0000000000000000
   179  
   180  > deliver_tx "abc"
   181  -> code: OK
   182  
   183  > info
   184  -> code: OK
   185  -> data: {"size":1}
   186  -> data.hex: 0x7B2273697A65223A317D
   187  
   188  > commit
   189  -> code: OK
   190  -> data.hex: 0x0200000000000000
   191  
   192  > query "abc"
   193  -> code: OK
   194  -> log: exists
   195  -> height: 2
   196  -> value: abc
   197  -> value.hex: 616263
   198  
   199  > deliver_tx "def=xyz"
   200  -> code: OK
   201  
   202  > commit
   203  -> code: OK
   204  -> data.hex: 0x0400000000000000
   205  
   206  > query "def"
   207  -> code: OK
   208  -> log: exists
   209  -> height: 3
   210  -> value: xyz
   211  -> value.hex: 78797A
   212  ```
   213  
   214  Note that if we do `deliver_tx "abc"` it will store `(abc, abc)`, but if
   215  we do `deliver_tx "abc=efg"` it will store `(abc, efg)`.
   216  
   217  Similarly, you could put the commands in a file and run
   218  `abci-cli --verbose batch < myfile`.
   219  
   220  ## Counter - Another Example
   221  
   222  Now that we've got the hang of it, let's try another application, the
   223  "counter" app.
   224  
   225  Like the kvstore app, its code can be found
   226  [here](https://github.com/tendermint/tendermint/blob/master/abci/cmd/abci-cli/abci-cli.go)
   227  and looks like:
   228  
   229  ```
   230  func cmdCounter(cmd *cobra.Command, args []string) error {
   231  
   232      app := counter.NewCounterApplication(flagSerial)
   233  
   234      logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
   235  
   236      // Start the listener
   237      srv, err := server.NewServer(flagAddrC, flagAbci, app)
   238      if err != nil {
   239          return err
   240      }
   241      srv.SetLogger(logger.With("module", "abci-server"))
   242      if err := srv.Start(); err != nil {
   243          return err
   244      }
   245  
   246      // Stop upon receiving SIGTERM or CTRL-C.
   247      tmos.TrapSignal(logger, func() {
   248          // Cleanup
   249          srv.Stop()
   250      })
   251  
   252      // Run forever.
   253      select {}
   254  }
   255  ```
   256  
   257  The counter app doesn't use a Merkle tree, it just counts how many times
   258  we've sent a transaction, asked for a hash, or committed the state. The
   259  result of `commit` is just the number of transactions sent.
   260  
   261  This application has two modes: `serial=off` and `serial=on`.
   262  
   263  When `serial=on`, transactions must be a big-endian encoded incrementing
   264  integer, starting at 0.
   265  
   266  If `serial=off`, there are no restrictions on transactions.
   267  
   268  We can toggle the value of `serial` using the `set_option` ABCI message.
   269  
   270  When `serial=on`, some transactions are invalid. In a live blockchain,
   271  transactions collect in memory before they are committed into blocks. To
   272  avoid wasting resources on invalid transactions, ABCI provides the
   273  `check_tx` message, which application developers can use to accept or
   274  reject transactions, before they are stored in memory or gossipped to
   275  other peers.
   276  
   277  In this instance of the counter app, `check_tx` only allows transactions
   278  whose integer is greater than the last committed one.
   279  
   280  Let's kill the console and the kvstore application, and start the
   281  counter app:
   282  
   283  ```
   284  abci-cli counter
   285  ```
   286  
   287  In another window, start the `abci-cli console`:
   288  
   289  ```
   290  > set_option serial on
   291  -> code: OK
   292  -> log: OK (SetOption doesn't return anything.)
   293  
   294  > check_tx 0x00
   295  -> code: OK
   296  
   297  > check_tx 0xff
   298  -> code: OK
   299  
   300  > deliver_tx 0x00
   301  -> code: OK
   302  
   303  > check_tx 0x00
   304  -> code: BadNonce
   305  -> log: Invalid nonce. Expected >= 1, got 0
   306  
   307  > deliver_tx 0x01
   308  -> code: OK
   309  
   310  > deliver_tx 0x04
   311  -> code: BadNonce
   312  -> log: Invalid nonce. Expected 2, got 4
   313  
   314  > info
   315  -> code: OK
   316  -> data: {"hashes":0,"txs":2}
   317  -> data.hex: 0x7B22686173686573223A302C22747873223A327D
   318  ```
   319  
   320  This is a very simple application, but between `counter` and `kvstore`,
   321  its easy to see how you can build out arbitrary application states on
   322  top of the ABCI. [Hyperledger's
   323  Burrow](https://github.com/hyperledger/burrow) also runs atop ABCI,
   324  bringing with it Ethereum-like accounts, the Ethereum virtual-machine,
   325  Monax's permissioning scheme, and native contracts extensions.
   326  
   327  But the ultimate flexibility comes from being able to write the
   328  application easily in any language.
   329  
   330  We have implemented the counter in a number of languages [see the
   331  example directory](https://github.com/tendermint/tendermint/tree/master/abci/example).
   332  
   333  To run the Node.js version, fist download & install [the Javascript ABCI server](https://github.com/tendermint/js-abci):
   334  
   335  ```
   336  git clone https://github.com/tendermint/js-abci.git
   337  cd js-abci
   338  npm install abci
   339  ```
   340  
   341  Now you can start the app:
   342  
   343  ```bash
   344  node example/counter.js
   345  ```
   346  
   347  (you'll have to kill the other counter application process). In another
   348  window, run the console and those previous ABCI commands. You should get
   349  the same results as for the Go version.
   350  
   351  ## Bounties
   352  
   353  Want to write the counter app in your favorite language?! We'd be happy
   354  to add you to our [ecosystem](https://github.com/tendermint/awesome#ecosystem)!
   355  See [funding](https://github.com/interchainio/funding) opportunities from the
   356  [Interchain Foundation](https://interchain.io/) for implementations in new languages and more.
   357  
   358  The `abci-cli` is designed strictly for testing and debugging. In a real
   359  deployment, the role of sending messages is taken by Tendermint, which
   360  connects to the app using three separate connections, each with its own
   361  pattern of messages.
   362  
   363  For more information, see the [application developers
   364  guide](./app-development.md). For examples of running an ABCI app with
   365  Tendermint, see the [getting started guide](./getting-started.md).
   366  Next is the ABCI specification.