本文是区块链浏览器系列的第三篇,本文介绍区块链浏览器的主体部分,即区块数据的解析。

这一版本的区块链浏览器是基于gin实现的,只提供三种接口:

  • /block/uploadPOST,上传Protobuf格式的区块数据文件
  • /block/parse/:msgTypeGET,根据msgType来解析上传的区块文件
  • /block/update/:channelPOST,根据上传的json格式配置文件生成Protobuf格式的文件

结构如下:

$ tree
.
├── LICENSE
├── README.md
├── cmd # 解析区块的示例
│   ├── main.go
│   ├── mychannel_config.block
│   └── mychannel_newest.block
├── conf # 浏览器的配置
│   ├── conf.pb.go
│   └── conf.proto
├── configs # 配置文件存放路径
│   └── config.yaml
├── go.mod
├── go.sum
├── log # 日志库
│   └── logger.go
├── main.go # 程序入口
├── service # 项目实现代码
│   ├── handler.go
│   ├── service.go
│   └── utils.go
└── utils # 一些工具函数
├── protoutils.go
└── utils.go 7 directories, 17 files

详细介绍

配置介绍

当前版本配置比较简单,使用Protobuf进行定义:

syntax = "proto3";

package browser.conf;

option go_package = "./;conf";

import "google/protobuf/duration.proto";

message Bootstrap {
Server server = 1;
Log log = 2;
} message Server {
message HTTP {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
message TLS {
// 是否启用tls
bool enbale = 1;
// 证书路径
string cert = 2;
// 对应私钥路径
string key = 3;
}
HTTP http = 1;
TLS tls = 2;
} message Log {
// 日志级别设置
// 支持debug(-1)、info(0)、warn(1)、error(2)、dpanic(3)、panic(4)、fatal(5)
int32 level = 1;
// 日志输出格式,支持json or console
string format = 2;
}

日志

log基于zap进行简单封装使用:

func DefaultLogger(logConf *conf.Log) *zap.Logger {
var coreArr []zapcore.Core //获取编码器
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder //指定时间格式
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder //按级别显示不同颜色
encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder //显示完整文件路径 var encoder zapcore.Encoder //NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式
if logConf.Format == "console" {
encoder = zapcore.NewConsoleEncoder(encoderConfig)
} else {
encoder = zapcore.NewJSONEncoder(encoderConfig)
} //日志级别
highPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { //error级别
return lev >= zap.ErrorLevel
})
lowPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { //info和debug级别,debug级别是最低的
return lev < zap.ErrorLevel && lev >= zap.DebugLevel
}) infoCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), lowPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志
errorCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), highPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志 coreArr = append(coreArr, infoCore)
coreArr = append(coreArr, errorCore) return setLogLevel(zap.New(zapcore.NewTee(coreArr...), zap.AddCaller()), logConf.GetLevel())
} func setLogLevel(log *zap.Logger, level int32) *zap.Logger {
switch level {
case -1:
return log.WithOptions(zap.IncreaseLevel(zapcore.DebugLevel))
case 0:
return log.WithOptions(zap.IncreaseLevel(zapcore.InfoLevel))
case 1:
return log.WithOptions(zap.IncreaseLevel(zapcore.WarnLevel))
case 3:
return log.WithOptions(zap.IncreaseLevel(zapcore.DPanicLevel))
case 4:
return log.WithOptions(zap.IncreaseLevel(zapcore.PanicLevel))
case 5:
return log.WithOptions(zap.IncreaseLevel(zapcore.FatalLevel))
default:
return log.WithOptions(zap.IncreaseLevel(zapcore.ErrorLevel))
}
}

service

service为本项目的主体,提供区块解析服务。

/block/upload/block/parse/:msgType二者配合使用。

/block/upload完成文件上传后,会存储在./pb目录下,通过session记录上传的Protobuf格式区块文件与用户交互:

type pbCache struct {
// 缓存session
cache sync.Map
// 定时器,超时后自动删除对应的pb文件
time *time.Ticker
} type pbFile struct {
// pb文件名称,文件存储在服务端的名称
Name string
// 文件过期时间,过期后自动删除
Expired int64
}

调用/block/parse/:msgType时,服务端通过loadSessionsession中获取,每次调用都会对当前pb文件自动续期:

func loadSession(ctx *gin.Context) (string, error) {
// get filename from session
session := sessions.Default(ctx)
buf := session.Get("filename")
if buf == nil {
srvLogger.Error("no filename in session")
return "", errors.New("no filename in session")
} // 更新pbFile过期时间
pf := &pbFile{}
pf.Unmarshal([]byte(buf.(string)))
pf.renewal() data, _ := pf.Marshal()
session.Set("filename", string(data))
session.Save()
return pf.Name, nil
}

msgType支持以下类型:

  • block:将上传的pb文件解析为json
  • header:获取区块header域信息
  • metadata:获取区块metadata域信息
  • data:获取区块的data域信息
  • config:获取配置块信息,如果解析的是数据块,将返回空信息
  • chaincode:获取智能合约信息
  • actionstransaction:区块中包含的交易信息
  • input:获取交易信息中的输入信息
  • rwset:获取交易中包含的读写集信息
  • channel:获取通道信息
  • endorsements:获取交易的背书信息
  • creator:获取交易发起者信息

调用/block/update/:channel时,可以将json格式的配置块信息转换为Protobuf格式。


声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意


Fabric区块链浏览器(1)的更多相关文章

  1. 第五章 FISCO BCOS 区块链浏览器的部署

    想了解相关区块链开发,技术提问,请加QQ群:538327407 前提 前面我们已经通过底层部署.sdk调测.自定义智能合约编写与部署.联合单元测试调测,已经初步对FISCO BCOS的区块链底层和实际 ...

  2. hyperledger explorer 结合 fabric1.4 搭建 区块链浏览器 踩坑记录

    博主通过这篇博客的步骤搭建区块链浏览器:https://blog.csdn.net/qq_32675427/article/details/99946945 进行到下面这一步时出现各种异常,浪费了博主 ...

  3. github源码开源区块链浏览器

    <ignore_js_op> 帅爆了吧 https://blockexplorer.com/ github源码:https://github.com/bitcoin-blockexplor ...

  4. 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1

    摘要: 全球开源区块链领域影响最为广泛的Hyperledger Fabric日前宣布了1.1版本的正式发布,带来了一系列丰富的新功能以及在安全性.性能与扩展性等方面的显著提升.阿里云容器服务区块链解决 ...

  5. 区块链学习7:超级账本项目Hyperledger与Fabric以及二者的关系

    ☞ ░ 前往老猿Python博文目录 ░ 一.超级账本(hyperledger) 超级账本(hyperledger)是Linux基金会于2015年发起的推进区块链数字技术和交易验证的开源项目,成员包括 ...

  6. 区块链学习7:超级账本项目Fabric中的背书、背书节点、背书策略、背书签名

    ☞ ░ 前往老猿Python博文目录 ░ 在Hyperledger Fabric区块链中,有背书节点进行背书,Hyperledger Fabric 使用背书策略来定义哪些节点需要执行交易. Hyper ...

  7. Hyperledger Fabric 2.x Java区块链应用

    一.说明 在上一篇文章中 <Hyperledger Fabric 2.x 自定义智能合约> 分享了智能合约的安装并使用 cli 客户端进行合约的调用:本文将使用 Java 代码基于 fab ...

  8. 如何从零开始学习区块链技术——推荐从以太坊开发DApp开始

    很多人迷惑于区块链和以太坊,不知如何学习,本文简单说了一下学习的一些方法和资源. 一. 以太坊和区块链的关系 从区块链历史上来说,先诞生了比特币,当时并没有区块链这个技术和名词,然后业界从比特币中提取 ...

  9. NEO区块链-DAPP开发直通车-第零篇

    什么是DAPP DAPP 是以太坊发明的词汇 Decentralized Application. 目前基于区块链技术开发的应用程序广泛的接受使用了这一名称.   NEL将为开发DAPP提供全面的服务 ...

  10. [币严区块链]BitcoinCash - BCH钱包地址生成与扫块充值监控(JAVA版)

    本文的方案无需自建节点,因为BCH当前区块数据大小已经达到200G以上,BTC区块数据也已超过300G,若每个币都自建节点,对云服务器的消耗会非常大. 认识BitcoinCash(BCH) Bitco ...

随机推荐

  1. 开心档之CSS 测验

    ​ 目录 CSS 测验 ​编辑 CSS 测验 CSS测验是一种衡量前端开发人员对CSS的熟练程度的测试.通过CSS测验,可以评估一个人对CSS语言的掌握程度和应用能力,帮助公司或招聘方挑选合适的人才. ...

  2. Solon 问答: 怎么切换环境配置?

    #应用配置文件活动选择(可用于切换不同的环境配置) solon.env: dev #例: # app.yml #应用主配置(必然会加载) # app-dev.yml #应用dev环境配置 # app- ...

  3. 【Vue】表单数据双向绑定 vue生命周期 fetch和axios发送请求 Vue全局组件

    目录 昨日回顾 表单数据双向绑定(重要) checkbox单选 --- 布尔值 checkbox多选 --- 数组 radio单选 --- 字符串 给后端发送数据 购物车案例 全选按钮 商品添加删除 ...

  4. COOIS增强

    一.订单抬头增强 二.结构添加字段 添加ZGCWL字段 三.BADI增强 四.其他界面增强 不同的界面,选择不同的修改结构 抬头 ct_ioheader 组件 ct_ioopcomp 工序 ct_io ...

  5. #1198:Farm Irrigation(DFS + 并查集)

    Farm Irrigation **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...

  6. Java面试——基础知识点

    JVM Jvm体系总体分四大块:类的加载机制.Jvm内存结构.GC算法垃圾回收.GC分析命令调优. 类的加载机制 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的 ...

  7. 继承 封装 多态 java的三大特性

    import java.util.Scanner;class A{ int ivar = 7; void m1(){ System.out.print("A's m1, "); } ...

  8. poj 3246 简单线段树

    线段树还真有点难写... #include <iostream> #include <cstdio> #include <cstring> #include < ...

  9. idea 修改 jsp文件之后不生效问题

  10. linux-网络状态-netstat