Fabric区块链浏览器(1)
1.iota简介2.go generate命令简介3.golang uuid库介绍4.gRPC基本教程5.protolator简介6.Govulncheck v1.0.0 发布了!7.每日一库:GORM简介8.Go泛型简介9.Go 1.21发布!10.Golang zip压缩文件读写操作11.本地搭建playground12.zap自定义日志级别13.Gorm日志设置14.gin启动https支持15.Go Plugin介绍16.Golang漏洞管理17.可以丢掉123456了18.如何优雅地退出程序19.PGO前瞻20.go多版本管理21.openAI发布v0.2.0了22.Gin中间件开发
23.Fabric区块链浏览器(1)
24.每日一库:Memcache25.protojson简介26.每日一库:gosec27.Fabric区块链浏览器(2)28.每日一库:fsnotify简介29.gRPC with JWT30.embed简介31.Fabric区块链浏览器(3)32.每日一库:pprof简介33.go 1.21:cmp34.完全可复制、经过验证的 Go 工具链35.PGO in Go 1.2136.Fabric 2.x 智能合约开发记录37.为不断增长的Go生态系统扩展gopls38.每日一库:lumberjack -- 日志轮换和管理39.2023-04-26-微信安全模式下消息解析40.WASI support in Go41.每日一库:Prometheus42.如何实现流量控制和熔断降级?43.消息队列 - RabbitMQ44.Go 1.22 中的 For 循环45.设计模式之单例模式46.每日一库:使用Viper处理Go应用程序的配置47.使用 gopkg.in/yaml.v3 解析 YAML 数据48.在Go中如何实现并发49.解析类型参数50.设计模式之工厂模式51.每日一库:cobra 简介52.slices in Go 1.2153.go defer简介54.slice简介55.Golang Map底层实现简述56.Go 如何实现多态57.查找数组中第K大的元素58.go中的内存逃逸59.数组 vs. 切片60.队列(Queue):先进先出(FIFO)的数据结构61.go 中如何实现定时任务62.go 中的循环依赖63.Go中字符串处理:fmt.Sprintf与string.Builder的比较64.理解Go中的零值65.go 上下文:context.Context66.go中异常处理流程67.Go实现网络代理68.Why gRPC ?69.Go:条件控制语句70.Go 获取 IP 地址71.Golang并发控制方式有几种?72.Golang面试:泛型73.LRU算法简介74.MRU算法实现75.ARC算法实现76.Go语言中的交互式CLI开发:survey库简介77.C如何调用Go本文是区块链浏览器系列的第三篇,本文介绍区块链浏览器的主体部分,即区块数据的解析。
- /block/upload:POST,上传Protobuf格式的区块数据文件
- /block/parse/:msgType:GET,根据
msgType
来解析上传的区块文件 - /block/update/:channel:POST,根据上传的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
时,服务端通过loadSession
从session中获取,每次调用都会对当前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:获取智能合约信息
- actions、transaction:区块中包含的交易信息
- 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: 恋水无意
分类:
Blockchain
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程