Fabric区块链浏览器(1)
本文是区块链浏览器系列的第三篇,本文介绍区块链浏览器的主体部分,即区块数据的解析。
- /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: 恋水无意
Fabric区块链浏览器(1)的更多相关文章
- 第五章 FISCO BCOS 区块链浏览器的部署
想了解相关区块链开发,技术提问,请加QQ群:538327407 前提 前面我们已经通过底层部署.sdk调测.自定义智能合约编写与部署.联合单元测试调测,已经初步对FISCO BCOS的区块链底层和实际 ...
- hyperledger explorer 结合 fabric1.4 搭建 区块链浏览器 踩坑记录
博主通过这篇博客的步骤搭建区块链浏览器:https://blog.csdn.net/qq_32675427/article/details/99946945 进行到下面这一步时出现各种异常,浪费了博主 ...
- github源码开源区块链浏览器
<ignore_js_op> 帅爆了吧 https://blockexplorer.com/ github源码:https://github.com/bitcoin-blockexplor ...
- 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
摘要: 全球开源区块链领域影响最为广泛的Hyperledger Fabric日前宣布了1.1版本的正式发布,带来了一系列丰富的新功能以及在安全性.性能与扩展性等方面的显著提升.阿里云容器服务区块链解决 ...
- 区块链学习7:超级账本项目Hyperledger与Fabric以及二者的关系
☞ ░ 前往老猿Python博文目录 ░ 一.超级账本(hyperledger) 超级账本(hyperledger)是Linux基金会于2015年发起的推进区块链数字技术和交易验证的开源项目,成员包括 ...
- 区块链学习7:超级账本项目Fabric中的背书、背书节点、背书策略、背书签名
☞ ░ 前往老猿Python博文目录 ░ 在Hyperledger Fabric区块链中,有背书节点进行背书,Hyperledger Fabric 使用背书策略来定义哪些节点需要执行交易. Hyper ...
- Hyperledger Fabric 2.x Java区块链应用
一.说明 在上一篇文章中 <Hyperledger Fabric 2.x 自定义智能合约> 分享了智能合约的安装并使用 cli 客户端进行合约的调用:本文将使用 Java 代码基于 fab ...
- 如何从零开始学习区块链技术——推荐从以太坊开发DApp开始
很多人迷惑于区块链和以太坊,不知如何学习,本文简单说了一下学习的一些方法和资源. 一. 以太坊和区块链的关系 从区块链历史上来说,先诞生了比特币,当时并没有区块链这个技术和名词,然后业界从比特币中提取 ...
- NEO区块链-DAPP开发直通车-第零篇
什么是DAPP DAPP 是以太坊发明的词汇 Decentralized Application. 目前基于区块链技术开发的应用程序广泛的接受使用了这一名称. NEL将为开发DAPP提供全面的服务 ...
- [币严区块链]BitcoinCash - BCH钱包地址生成与扫块充值监控(JAVA版)
本文的方案无需自建节点,因为BCH当前区块数据大小已经达到200G以上,BTC区块数据也已超过300G,若每个币都自建节点,对云服务器的消耗会非常大. 认识BitcoinCash(BCH) Bitco ...
随机推荐
- 企业新道路怎么走?火山引擎AB测试助力决策选择
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 乐刻是一家创立8年的企业,除了消费者熟悉的乐刻健身房可办月卡.24小时营业等,其还有比外界了解更多元的业务.目 ...
- 对话 BitSail Contributor | 吴畅:从好奇,到深入
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 2022 年 10 月,字节跳动 BitSail 数据引擎正式开源.同期,社区推出 Contributor 激励计 ...
- Live Server插件打开浏览器时:该网页无法正常运作,127.0.0.1未发送任何数据的问题解决
一.问题复现 今天使用Vs Code写HTML代码时,使用Live Server打开预览时,发现浏览器显示"该网页无法正常运作,127.0.0.1未发送任何数据"的问题. 二.解决 ...
- mybatis-plus Date类型的参数 只有年月日 没有时分秒的解决办法
问题: 使用mybatis-plus 设计实体的时候 使用 Date inTime; 数据库里的时间2021-11-05 22:00:13 但java里的时间变成了2021-11-05 00: ...
- 《3D编程模式》写书-第2次记录
大家好,目前我已经完成了"拼接模式"."撤销重做模式"."ECS模式"的初稿 下面会给出它们的使用场景,如果您正好能用到,请联系我提前阅读模 ...
- vue权限管理
https://www.bilibili.com/video/BV1nq4y1i7BU/?spm_id_from=333.788.recommend_more_video.6&vd_sourc ...
- SpringBoot 集成短信和邮件
准备工作 1.集成邮件 以QQ邮箱为例 在发送邮件之前,要开启POP3和SMTP协议,需要获得邮件服务器的授权码,获取授权码: 1.设置>账户 在账户的下面有一个开启SMTP协议的开关并进行密码 ...
- Go ASM 学习笔记之 ppt 版
在 小白学标准库之反射 reflect 篇中介绍了接口和反射.然而,对于接口的类型转换,底层实现还是一知半解.在参考 Go 语言设计与实现 这本书接口章节时,又看不大懂.一个拦路虎摆在面前:汇编.不懂 ...
- 【PID】初学者的pid,详细的介绍了代码为什么是这样写的
from:Improving the Beginner's PID – Introduction « Project Blog (brettbeauregard.com)
- iframe访问页面,出现 ERR_BLOCKED_BY_RESPONSE
那是因为服务器输出了 X-Frame-Options 头,只要把这个头删除掉,就没问题了