Fabric区块链浏览器(1)

fabric,区块,浏览器 · 浏览次数 : 23

小编点评

**区块链浏览器的主体部分** 区块链浏览器是一个基于 Gin 框架的程序,提供三种接口: * `/block/upload`:用于上传 pb 文件以解析为 JSON header。 * `/block/parse/:msgType`:用于解析上传的区块文件并返回区块数据。 * `/block/update/:channel`:用于根据上传的 JSON 配置文件生成 Protobuf 格式的文件结构,并生成包含区块数据和配置信息的 Protobuf 文件。 **区块数据解析** 区块数据解析使用 `protobuf3` 库进行定义,并通过 `zapcore` 库进行封装。解析过程包括: 1. 接收区块数据。 2. 使用 `protobuf3` 库将数据解码为 `Bootstrap` 结构。 3. 从结构中提取区块信息,例如 server、log、data、config 等。 **主要函数** * `serviceservice`:提供区块解析服务,包括 `loadSession` 和 `saveSession` 方法。 * `pbCache`:缓存 pb 文件,并自动续期。 * `pbFile`:封装区块数据,包括名称和发布时间。 * `msgType`:支持的区块类型。

正文

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

这一版本的区块链浏览器是基于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)相似的内容:

Fabric区块链浏览器(1)

本文是区块链浏览器系列的第三篇,本文介绍区块链浏览器的主体部分,即区块数据的解析。 这一版本的[区块链浏览器](https://github.com/mengbin92/browser/tree/gin)是基于[gin](https://github.com/gin-gonic/gin)实现的,只提

Fabric区块链浏览器(2)

本文是区块链浏览器系列的第四篇。 在[上一篇文章](https://mengbin.top/2023-08-13-blockBrowser/)介绍如何解析区块数据时,使用`session`对客户端上传的pb文件进行区分,到期后自动删除。 在这片文章中,会着重介绍下认证系统的实现,主要分为三部分: -

Fabric区块链浏览器(3)

本文是区块链浏览器系列的第五篇,项目完整代码在[这里](https://github.com/mengbin92/browser/tree/main)。 在[上一篇文章](https://mengbin.top/2023-08-20-browser2/)中给浏览器增加了简单的用户认证,至此浏览器的基

Fabric配置块结构解析

本文是区块链浏览器系列的第二篇。 上一篇介绍了交易块中的数据结构,这一篇介绍区块链网络中的配置块数据结构。 这两种区块中数据结构内容的区别主要Payload结构体中的Data域中的内容,接下来将以类图的形式来解析Data域包含的信息: classDiagram class Payload{ Head

从源码中解析fabric区块数据结构(一)

从源码中解析fabric区块数据结构(一) 前言 最近打算基于fabric-sdk-go实现hyperledger fabric浏览器,其中最重要的一步就是解析fabric的上链区块。虽说fabric是Golang实现的,但直到2021年2月1号才发布了第一个稳定版fabric-sdk-go,而且官

基于密码学的身份混淆系统 -- idmix

## 简介 Hyperledger Fabric的Idemix是一个基于密码学的身份混淆系统,它提供了一种在区块链网络中实现用户隐私的方法。Idemix的主要特性是它的零知识证明系统,这是一种允许用户证明他们拥有某些属性,而无需透露任何其他信息的技术。 以下是一些更详细的关于Idemix的信息: 1

Fabric 2.x 智能合约开发记录

表象:Return schema invalid. required items must be unique [recovered] 虽然 Fabric v2.2 已经发布了很久了,但之前因为项目历史问题,一直使用的都是 Fabric v1.4.8,所以智能合约也一直使用的都是 github.co

【Azure Service Fabric】关于Service Fabric的相关问题

问题一:Service Fabric 是否支持Private Link? 在Azure Private Endpoint文档中,罗列出了 Azure 上支持 Private Link 的服务。Service Fabric不在其中。 Azure Private Link availability :h

Hyperledger Fabric系统链码介绍

在Hyperledger Fabric中,LSCC(Lifecycle System Chaincode)、CSCC(Chaincode System Chaincode)、QSCC(Query System Chaincode)、ESCC(Endorsement System Chaincode)

【Azure Fabric Service】Service Fabric 托管群集通过 Connect-ServiceFabricCluster 连接时候报错 CertificatedNotMatched

问题描述 Service Fabric 托管群集, 使用Key Vault中证书,把证书导入到本地安装后,使用该证书的 Thumbprint 作为指令 Connect-ServiceFabricCluster 的 ServerCertThumbprint 和FindValue 的值。结果连接失败,错