最佳实践

应用使用区块链进行数据存证时,一般根据应用场景可以分为两类模式

  • 数据存证模式
  • 数据存取模式

数据存证模式指利用区块链不可篡改,共识时间撮的技术特性,将区块链应用为数据存证系统。该模式下,应用将关键的业务凭证信息(如合同、支付凭证等关键业务信息)写入区块链,应用保存区块链交易hash存根,将区块链视为存证系统。当有举证需求时,根据区块链的交易hash查询之前存证的原始数据以证明业务凭证信息的存在性。

数据存取模式指利用区块链不可篡改,分布式的技术特性,将区块链应用为可信分布式账本,完成基于共享的可信的数据账本的分布式业务协作。该模式下,应用将关键的业务数据写入区块链,多个参与方可根据业务数据属性在链上准实时查询检索业务数据。

以下介绍两种常用的应用交互模式。

数据存证交互模式

存证模式下,区块链系统职责是一个存证系统,共识并储存业务的存证数据,业务在需要时根据交易Hash从区块链查询原始存证数据。

应用交互流程

  1. 应用远程调用区块链节点写入数据
  2. 区块链节点写入交易池
  3. 区块链节点返回受理成功
  4. 应用保存交易Hash,与本地业务配置关联
  5. 区块链异步完成数据共识上链
  6. 应用根据交易Hash查询区块链交易(存在性证明)

内容存证查询

  1. // 加载client配置文件
  2. Properties p = new Properties();
  3. p.load(new FileInputStream("sdk.properties"));
  4. ClientConfig config = new ClientPropertyConfig(p);
  5. // 使用指定client配置初始化client
  6. Client client = new Client(config);
  7. // 根据tx Hash查询
  8. Response<TransactionDO> response =client.getTransaction("462da7df7c10f9b12137549b83bd77b7335cfdd5bf8a060013a111748b564e94");
  9. if(response.isSuccess()){
  10. TransactionDO tx = response.getData();
  11. // 查询成功
  12. if(null == tx){
  13. // 链上未存在该Tx
  14. return null;
  15. }
  16. // 根据交易类型读取具体交易内容
  17. if (tx.getType() == PayloadType.TX_TYPE_NOTARY_CONTENT_ONLY.code) {
  18. // 读取内容存证交易
  19. // case the payload type
  20. ContentOnlyNotaryPayloadDO payloadDO = (ContentOnlyNotaryPayloadDO)tx.getPayload();
  21. // do something about the payload
  22. // ...
  23. // read content
  24. System.out.println(new String(payloadDO.getContent(), "UTF-8"));
  25. // read biz time
  26. System.out.println(payloadDO.getTimestamp());
  27. }
  28. return tx.getTxHashValue()
  29. }else{
  30. // 查询异常,
  31. }

Block查询

  1. // 加载client配置文件
  2. Properties p = new Properties();
  3. p.load(new FileInputStream("sdk.properties"));
  4. ClientConfig config = new ClientPropertyConfig(p);
  5. // 使用指定client配置初始化client
  6. Client client = new Client(config);
  7. // 查询区块高度
  8. Response<Block> response = client.getBlock(4);
  9. if(response.isSuccess()){
  10. // 查询成功
  11. if(null == response.getData()){
  12. // 链上未存在该块
  13. return null;
  14. }
  15. // read block
  16. // ....
  17. }

数据存取交互模式

数据存取模式下,区块链系统应用为一个分布式账本,多个参与方共同读写共享账本完成分布式协作。

数据存取系统架构

为了满足多样化的业务领域扩展需求,数据存取模式下区块链架构分为2层

  • 区块链
  • 业务系统

区块链完成数据共识,账本存储,及提供交易验证能力。

业务系统实时同步区块链账本,按业务需求处理区块上的交易信息,完成定制化业务逻辑、数据存储与相关索引建立。业务系统可以集群化部署,提供稳定高效的查询能力。

整体交互流程:

  1. 应用远程调用区块链节点写入数据
  2. 区块链节点写入交易池,返回受理成功
  3. 区块链异步完成数据共识上链,并发布出块通知
  4. 业务系统订阅并接收区块链节点出块通知,按需从区块链拉取区块
  5. 业务系统根据业务需求处理交易数据,格式化存储,建立相关业务索引
  6. 应用根据业务数据属性查询链上数据

出块事件订阅

  1. // 订阅节点的出块事件,当节点生成区块时会发送推送区块通知
  2. // 远程节点当有区块生成时会回调Consumer,在Consumer处理出块通知即可
  3. // groupId相同的订阅方,只选择一台推送
  4. Response<Boolean> response = client.subscribeBlockEvent("group0", new Consumer<NewBlockEventBody>() {
  5. @Override
  6. public void accept(NewBlockEventBody body) {
  7. // 获取块高
  8. Long final_height = body.getHeight();
  9. // 拉取区块并处理交易数据,格式化存储
  10. // ...
  11. }
  12. });
  13. if(!response.isSuccess()){
  14. // 订阅失败
  15. // 处理失败流程
  16. }

除事件订阅外,还可以通过定时任务的方式获取最新区块。

  1. @Scheduled(cron="* 1/1 * * * *")
  2. public void fetchBlock() {
  3. final Response<BlockHeader> blockHeader = client.getLatestBlockHeader();
  4. if(!blockHeader.isSuccess()) {
  5. LOGGER.error("Get block header fail: ", blockHeader.getErrorMsg());
  6. return;
  7. }
  8. // 获取块高
  9. long finalHeight = blockHeader.getData().getHeight();
  10. // 拉取区块并处理交易数据,格式化存储
  11. // ...
  12. }