Skip to content

获得区块推送,搭建自己的应用

QM edited this page Dec 21, 2020 · 1 revision

推送功能说明

在chain33公链架构中, 区块推送是一个有特色的功能。

一般上区块链在共识机制上分为确定型和概率型。 chain33公链是使用概率型的共识, 即有可能在出块后发生分叉回滚。

要做基于chain33 公链的应用想在公链上获得数据做实时性的功能的话,需要处理分叉回滚。区块推送解决的是就是这个问题。 应用只需要订阅区块推送, 区块链节点就回将出块、回滚等情况序列话,依次推送出来。

比如节点在高度3发送回滚,应用收到的推送序列如下, 应用只需要跟着序列处理数据就可以了, 不需要再由应用本身来处理分叉。 推送功能简化了应用开发, 可以提高开发的效率。

 0:出块0 -> 1: 出块1 -> 2: 出块2 -> 3: 出块3 -> 4: 回滚区块3(回滚后区块链高度为2) -> 5: 出块3(这是新的区块3)

原理

chain33 提供区块推送接口

  1. 接口1: 注册
  2. 接口2: 获得
  3. 接口: 取消

步骤

注册获得区块推送的服务器

向对应的区块链节点发送注册区块推送的服务器信息

$ curl -X GET -d '{ "params" : [ {"name" : "test", "url" : "http://192.168.3.33:9999", "encode" : "json"  } ], "id" : 1, "method" : "Chain33.AddSeqCallBack" }' http://192.168.3.8:8801


{
    "id": 1,
    "result": {
        "isOK": true,
        "msg": ""
    },
    "error": null
}
  1. 接口为 Chain33.AddSeqCallBack
  2. name为推送名字, 向同一个节点注册, 不可以重复
  3. url 为接受推送的地址
  4. encode: 支持 json protobuf

推送收到的格式和回复

  1. 节点会向 注册的url发送区块
    1. http header: Content-type: gzip 目前只支持gzip 压缩
    2. body为 json/protobuf 格式 BlockSeq(具体结果,在文档最下方) 的信息, 格式由注册时指定
  2. 接受推送处理后需要回复信息
    1. 处理成功需要在http body 中回复 OK 或 ok
    2. 失败返回其他信息

取消推送

  1. 接口如注册, 在url 项填写空字符串
$ curl -X GET -d '
{ "params" : [ {"name" : "test", "url" : "", "encode" : "json"  } ], "id" : 1, "method" : "Chain33.AddSeqCallBack" }' http://192.168.3.8:8801

返回信息

{
    "id": 1,
    "result": {
        "isOK": true,
        "msg": ""
    },
    "error": null
}

BlockSeq 定义

type BlockSeq struct {
	Num                  int64          `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"`
	Seq                  *BlockSequence `protobuf:"bytes,2,opt,name=seq,proto3" json:"seq,omitempty"`
	Detail               *BlockDetail   `protobuf:"bytes,3,opt,name=detail,proto3" json:"detail,omitempty"`
	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
	XXX_unrecognized     []byte         `json:"-"`
	XXX_sizecache        int32          `json:"-"`
}

type BlockSequence struct {
	Hash                 []byte   `protobuf:"bytes,1,opt,name=Hash,proto3" json:"Hash,omitempty"`
	Type                 int64    `protobuf:"varint,2,opt,name=Type,proto3" json:"Type,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}
type BlockDetail struct {
	Block                *Block         `protobuf:"bytes,1,opt,name=block,proto3" json:"block,omitempty"`
	Receipts             []*ReceiptData `protobuf:"bytes,2,rep,name=receipts,proto3" json:"receipts,omitempty"`
	KV                   []*KeyValue    `protobuf:"bytes,3,rep,name=KV,proto3" json:"KV,omitempty"`
	PrevStatusHash       []byte         `protobuf:"bytes,4,opt,name=prevStatusHash,proto3" json:"prevStatusHash,omitempty"`
	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
	XXX_unrecognized     []byte         `json:"-"`
	XXX_sizecache        int32          `json:"-"`
}