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