tendermint提供的RPC接口(一)

准备工作:作者是在windows环境上进行的部署测试,其他环境也是大同小异。可参考往期文章windows环境下tendermint的编译与使用
本文用的是官方的KVStore的例子来测试api,为了更好的显示测试结果,修改了部分代码,详细如下:
DeliverTx
func (app *KVStoreApplication) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
   fmt.Println(“—————– kvStore DeliverTx”)
   var key, value []byte
   parts := bytes.Split(req.Tx, []byte(“=”))
   if len(parts) == 2 {
      key, value = parts[0], parts[1]
   } else {
      key, value = req.Tx, req.Tx
   }
   app.state.db.Set(prefixKey(key), value)
   app.state.Size += 1
   events := []types.Event{
      {
         Type: “app”,
         Attributes: []cmn.KVPair{
            {Key: []byte(“creator”), Value: []byte(“Cosmoshi Netowoko”)},
            {Key: []byte(“key”), Value: key},
         },
      },
   }
   return types.ResponseDeliverTx{Code: code.CodeTypeOK, Events: events,Log:”DeliverTx OK”} //此处增加Log,方便测试
}
CheckTx
func (app *KVStoreApplication) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx {
   fmt.Println(“—————– kvStore CheckTx”)
   return types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1,Log:”CheckTx OK”} //此处增加Log,方便测试}
由于篇幅比较长,计划分为2-3篇。
下面开始正文
1,Tx(发送交易)
/broadcast_tx_sync
说明:发送同步交易,从CheckTx返回相应值,不会等待DeliverTx的结果。
如果想确保这笔交易被打包了,可以通过订阅来实现(详见下文Websocket模块)。如果几个块内没有收到任何消息的话,重新发送这笔交易,如果还是没有收到,可以向其他节点发送这笔交易。订阅频道收不到消息的原因可能有:
1,恶意节点丢弃了这笔交易。
2,恶意提议者(没有必要与你通信的人)丢弃了可能在将来生效的交易(https://github.com/tendermint/tendermint/issues/3322)。
示例:
C:\Users\ch>curl -s localhost:26657/broadcast_tx_sync?tx=\”author=caohuan\”
{
  “jsonrpc”: “2.0”,
  “id”: “”,
  “result”: {
    “code”: 0,
    “data”: “”,
    “log”: “CheckTx OK”, //可以看到这里的返回值就是CheckTx的返回值
    “hash”: “B339C04B9163F0585B8DB0703E2A107A9B21034B2F5D18BF9B66BDEF5DD627E3”
  }
}
/broadcast_tx_async
说明:发送异步交易,无返回值,不等待CheckTx或者DeliverTx的执行结果
详细说明同上。
示例:
C:\Users\ch>curl -s localhost:26657/broadcast_tx_async?tx=\”author=caohuan1\”
{
  “jsonrpc”: “2.0”,
  “id”: “”,
  “result”: {
    “code”: 0,
    “data”: “”,
    “log”: “”, //既不是CheckTx也不是DeliverTx    “hash”: “ED86886438919C7673ACBD0C649688D95A2D0CA3425A1350E68644AE367411AA”
  }
}
/broadcast_tx_commit
说明:既返回CheckTx的执行结果也返回DeliverTx的执行结果。
需要注意的是,官方建议仅仅在测试和开发的时候使用此接口,在生产环境,尽可能的使用同步或者异步的方式发送交易,如果要确认交易成功,可以使用订阅的功能。
如果CheckTx或则DeliverTx失败了,不会返回任何的错误信息,只会返回一个包含non-OK的ABCI code。
示例:
C:\Users\ch>curl -s localhost:26657/broadcast_tx_commit?tx=\”author=caohuan12\”
{
  “jsonrpc”: “2.0”,
  “id”: “”,
  “result”: {
    “check_tx”: { //CheckTx的返回值
      “log”: “CheckTx OK”, 
      “gasWanted”: “1”
    },
    “deliver_tx”: { //DeliverTx的返回值
      “log”: “DeliverTx OK”,
      “events”:
        {
          “type”: “app”,
          “attributes”: [
            {
              “key”: “Y3JlYXRvcg==”,
              “value”: “Q29zbW9zaGkgTmV0b3dva28=”
            },
            {
              “key”: “a2V5”,
              “value”: “YXV0aG9y”
            }
          ]
        }
      ]
    },
    “hash”: “95C3A05EC5FBE8E4F5D4FC690398E0D9AD8B7777A4D9A130982853F9647633C9”,
    “height”: “7”
  }
}
2,Websocket(订阅及取消订阅)
/subscribe
说明:通过wensocket订阅事件。
想要订阅某个事件,需要提供一个字符串表达式,格式是“condition AND condition ”(只能用AND不能用OR)。condition的格式是“key operation operand”,
key是一个字符串(\t\n\r()'”=><不允许出现在key中)
operation可以是“=”,“”,“> =”, “CONTAINS”
operand可以是一个字符串(要用单引号转义),数字,日期或者事件。
比如:
tm.event = ‘NewBlock’ // 新区快产生
tm.event = ‘CompleteProposal’ // 完成一个提案
tm.event = ‘Tx’ AND tx.hash = ‘XYZ’ // 某一笔交易
tm.event = ‘Tx’ AND tx.height = 5 // 第五个块的所有交易
tx.height = 5 // 第五个块的所有交易
tendermint提供了几个预定义的key:tm.ecent,tx.hash,tx.height。但是用户可以通过重定义DeliverTx的响应来增加key,用以订阅其他的事件。这个比较复杂,改天重新写一篇文章来详细阐述。
示例:
循环发送十笔交易

tendermint提供的RPC接口(一)

结果:

tendermint提供的RPC接口(一)

上面代码里面的tx是可以解析的。
/unsubscribe
说明:取消订阅
示例:
订阅的代码中设置一个计数器,超过十笔交易,即取消订阅

tendermint提供的RPC接口(一)

/unsubscribe_all
说明:取消所有订阅
示例:

tendermint提供的RPC接口(一)

结果和上面取消单个订阅的一样,不再截图了
3,ABCI
/abci_info
说明:获取应用的一些信息
示例:
C:\Users\ch>curl -s localhost:26657/abci_info
{
  “jsonrpc”: “2.0”,
  “id”: “”,
  “result”: {
    “response”: {
      “data”: “{\”size\”:88}”, //所有交易数量      “version”: “0.16.1”, //abci-cli的版本信息      “app_version”: “1”
    }
  }
}
/abci_query
说明:查询某一笔交易,四个参数:data,path,height,prove,前两个为必填
示例:
C:\Users\ch>curl -s localhost:26657/abci_query?data=\”author\”
{
  “jsonrpc”: “2.0”,
  “id”: “”,
  “result”: {
    “response”: {
      “log”: “exists”,
      “key”: “YXV0aG9y”,
      “value”: “Y2FvaHUxYW4xMjMxMTQxMTExMTExMQ==”
    }
  }
}
官方文档里还有一个必填参数path,实际操作中发现不填也没有关系,还有两个选填参数height和prove,看起来好像都没有什么用处,填与不填对结果没什么影响。查证后再补充。