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

这一版本的区块链浏览器是基于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. appuploader 常规使用登录方法

      转载:登录appuploader 登录appuploader   常规使用登录方法 双击appuploader.exe 启动appuploader 点击底部的未登录,弹出登录框 在登录框内输入ap ...

  2. 使用 docker-compose 部署 folkmq 消息中间件

    仓库拉取 docker-compose.yml 文件: https://github.com/noear/folkmq/tree/main/deploy version: '3.5' services ...

  3. Solon2 开发之IoC,二、构建一个 Bean 的三种方式

    1.手动 简单的构建: //生成普通的Bean Solon.context().wrapAndPut(UserService.class, new UserServiceImpl()); //生成带注 ...

  4. Axure 单键快捷键

    如果怕误操作,可以把它关闭

  5. Hugging Face: 代码生成模型的预训练和微调

    和大家分享我们的机器学习工程师 Loubna Ben Allal 在 10 月上海 KubeCon 大会的主题演讲 题目是: 代码生成模型的预训练和微调 演讲介绍了构建和训练大型代码模型比如: Sta ...

  6. leaflet 绘制 点 线 面 圆 椭圆 线缓冲区

    leaflet有个绘图插件Leaflet.draw,但是我不想要它的控件,只想用它的绘制功能,控件我自己提供,当时不知道如何使用,就自己写了个绘制点线面圆和椭圆的工具,代码如下: /// <re ...

  7. 【每日一题】39. Contest(树状数组 / 容斥分治)

    补题链接:Here 算法涉及:树状数组.CDQ分治 n支队伍一共参加了三场比赛. 一支队伍x认为自己比另一支队伍y强当且仅当x在至少一场比赛中比y的排名高. 求有多少组(x,y),使得x自己觉得比y强 ...

  8. ifelse优化方案

    优化 if else:https://blog.csdn.net/FBB360JAVA/article/details/103832405 利用java8特性优化: https://blog.csdn ...

  9. 使用element-plus的el-scrollbar时滚动条没有显示出来但是页面可以滚动的解决办法

    如果使用 Element UI 的 el-scrollbar 组件时,滚动条没有显示出来但页面可以滚动,可以尝试调用其 update 方法来更新滚动条. 在适当的时机(例如在数据加载完成后或组件更新后 ...

  10. 传智黑马git学习笔记