LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 币圈百科 > 超级账本Hyperledger Fabric中的Protobuf到底是什么?

超级账本Hyperledger Fabric中的Protobuf到底是什么?

2020-05-18 区块链大本营 来源:火星财经

作者|DeeptimanPattnaik 译者|火火酱,责编|Carol

在本文中,我将解释如何在超账本HyperledgerFabric中使用Protobuf对数据进行序列化和结构化。Protobuf简化了HyperledgerFabric中数据处理和格式化过程。它使用特殊生成的源代码产生数据,从而在同一个智能合约中轻松地写入和读取数据。

Chaincode和SmartContract


在hyperledgerfabric中,Chaincode(链码)是一个特定的程序,被用于处理由区块链网络的参与者所同意的核心业务逻辑。Hyperledgerfabric还使用了一种名为SmartContract的数据格式技术,该技术是为Chaincode中的一组特定数据模型定义的。Chaincode可以有多组SmartContract,这些SmartContract可以控制不同数据模型的事务逻辑。简单来说,SmartContract管理事务,而Chaincode管理如何部署SmartContract。


例如:如果需要将一些用户信息记录存储到分类帐中,那么我们就需要一个能够定义单个记录所需数据字段的SmartContract。

User(用户)SmartContract


typeUserstruct{
IDstring`json:"id"`
Emailstring`json:"email"`
Namestring`json:"name"`
Mobilestring`json:"mobile"`
Agestring`json:"age"`
}

在该SmartContract中,有ID、电子邮件、姓名、移动电话、年龄等与个人用户记录相关的数据字段。同样,如果我们需要存储每位用户的财务记录,那么我们就需要另一种名为Financial的smartcontract。

Financial(金融)SmartContract


typeFinancialstruct{
IDstring`json:"id"`
BankNamestring`json:"bankName"`
IFSCCodestring`json:"ifscCode"`
AccNumberstring`json:"accNumber"`
CreatedDatestring`json:"createdDate"`
}

这两个smartcontract将被部署到Chaincode中,并且将处理两个分类帐状态——世界状态(WorldState)区块链的事务逻辑。

SmartContract在世界状态下主要执行Put、Get、Delete和GetHistory。

1.PutState——为每个不同的键创建新对象,或者覆盖现有对象。

2.GetState——从分类帐状态中检索不同键的对象。

3.DelState——从分类账的世界状态中移除对象。

4.GetHistoryForKey——返回跨时间键的所有交易历史记录。

所有记录都作为世界状态记录被存储在CouchDB中。对象以JSON格式存储为键值对。CouchDB能更快地从数据库中查询JSON集合。在区块链状态下,所有这些记录都被存储在字节中,并且是不可变的。

Protobuf


协议缓冲区(简称protobuf)是谷歌的序列化结构化数据,其无关语言和平台,并且具有可扩展机制。与传统的数据格式(如XMLJSON)相比,序列化结构化数据以字节为单位进行编译,因此更小、更快、更简单。

为什么要使用Protobuf?


如我们所见,有UserFinancial两个smartcontract将信息存储在同一个用户的分类账中,即User存储用户的基本的信息,Financial存储用户银行账户的详细信息。

但是,如果我们从查询目的的角度来看smartcontract的话,两个数据集之间就没有关系了。我们不能为UserFinancial数据模型定义相同的ID作为键,因为分类帐数据存储在键值对中,如果出现相同的键,则信息将被覆盖。

这两条记录将在分类账状态中以两个不同的ID进行存储

为了解决这个问题,Protobuf提供了一个更快、更灵活的解决方案。我们只需编写一个.proto文件来描述数据结构,在本例中,是我们要存储的Financial数据结构。

因此,protobuf消息格式的字节结果直接调用到UserSmartContract并完全删除FinancialSmartContract。

Protobuf是如何运作的?


接下来,我们将了解如何设置protobuf编译器并生成protobuf消息格式。

安装


首先,我们需要遵循一定的安装流程才能使用protobuf-compiler

$gogetgithub.com/golang/protobuf
$gogetgithub.com/golang/protobuf/proto
$goget-ugithub.com/golang/protobuf/protoc-gen-go
$exportPATH=$PATH:$GOPATH/bin

现在,安装protobuf-compiler

$sudoaptinstallprotobuf-compiler

然后,在命令行中输入protoc’。应该会显示‘Missinginputfile’(缺少输入文件),这表示protobuf-compiler已经成功安装。

示例

首先,我们需要创建一个financial.proto文件。它由Financial类型的消息格式组成,包含四个字段:银行名称、ifsc代码、帐号、创建日期。

financial.proto

syntax="proto3";
packagemain;
messageFinancial{
stringbankName=1;
stringifscCode=2;
stringaccNumber=3;
stringcreatedDate=4;
}

编译该proto文件,生成用于Financial消息格式的protobuf数据模型文件。

$protoc--go_out=.*.proto

你会看到protobuf文件已生成为financial.pb.go。该文件是与proto包兼容的数据模型,将被用于把proto消息格式转换为字节。

financial.pb.go

//Codegeneratedbyprotoc-gen-go.DONOTEDIT.
//source:financial.proto
packagemain
import(
fmt"fmt"
proto"github.com/golang/protobuf/proto"
math"math"
)
//Referenceimportstosuppresserrorsiftheyarenototherwiseused.
var_=proto.Marshal
var_=fmt.Errorf
var_=math.Inf
//Thisisacompile-timeassertiontoensurethatthisgeneratedfile
//iscompatiblewiththeprotopackageitisbeingcompiledagainst.
//Acompilationerroratthislinelikelymeansyourcopyofthe
//protopackageneedstobeupdated.
const_=proto.ProtoPackageIsVersion3//pleaseupgradetheprotopackage
typeFinancialstruct{
BankNamestring`protobuf:"bytes,1,opt,name=bankName,proto3"json:"bankName,omitempty"`
IfscCodestring`protobuf:"bytes,2,opt,name=ifscCode,proto3"json:"ifscCode,omitempty"`
AccNumberstring`protobuf:"bytes,3,opt,name=accNumber,proto3"json:"accNumber,omitempty"`
CreatedDatestring`protobuf:"bytes,4,opt,name=createdDate,proto3"json:"createdDate,omitempty"`
XXX_NoUnkeyedLiteralstruct{}`json:"-"`
XXX_unrecognized[]byte`json:"-"`
XXX_sizecacheint32`json:"-"`
}


func(m*Financial)Reset(){*m=Financial{}}
func(m*Financial)String()string{returnproto.CompactTextString(m)}
func(*Financial)ProtoMessage(){

func(*Financial)Descriptor()([]byte,[]int){
returnfileDescriptor_a283ebe7677acfbc,[]int{0}
}


func(m*Financial)XXX_Unmarshal(b[]byte)error{
returnxxx_messageInfo_Financial.Unmarshal(m,b)
}


func(m*Financial)XXX_Marshal(b[]byte,deterministicbool)([]byte,error){
returnxxx_messageInfo_Financial.Marshal(b,m,deterministic)
}


func(m*Financial)XXX_Merge(srcproto.Message){
xxx_messageInfo_Financial.Merge(m,src)
}


func(m*Financial)XXX_Size()int{
returnxxx_messageInfo_Financial.Size(m)
}


func(m*Financial)XXX_DiscardUnknown(){
xxx_messageInfo_Financial.DiscardUnknown(m)
}


varxxx_messageInfo_Financialproto.InternalMessageInfo
func(m*Financial)GetBankName()string{
ifm!=nil{
returnm.BankName
}
return""
}


func(m*Financial)GetIfscCode()string{
ifm!=nil{
returnm.IfscCode
}
return""
}


func(m*Financial)GetAccNumber()string{
ifm!=nil{
returnm.AccNumber
}
return""
}


func(m*Financial)GetCreatedDate()string{
ifm!=nil{
returnm.CreatedDate
}
return""
}


funcinit(){
proto.RegisterType((*Financial)(nil),"main.Financial")
}


funcinit(){proto.RegisterFile("financial.proto",fileDescriptor_a283ebe7677acfbc)}


varfileDescriptor_a283ebe7677acfbc=[]byte{
//136bytesofagzippedFileDescriptorProto
0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0xff,0xe2,0xe2,0x4f,0xcb,0xcc,0x4b,
0xcc,0x4b,0xce,0x4c,0xcc,0xd1,0x2b,0x28,0xca,0x2f,0xc9,0x17,0x62,0xc9,0x4d,0xcc,
0xcc,0x53,0x6a,0x66,0xe4,0xe2,0x74,0x83,0xc9,0x08,0x49,0x71,0x71,0x24,0x25,0xe6,
0x65,0xfb,0x25,0xe6,0xa6,0x4a,0x30,0x2a,0x30,0x6a,0x70,0x06,0xc1,0xf9,0x20,0xb9,
0xcc,0xb4,0xe2,0x64,0xe7,0xfc,0x94,0x54,0x09,0x26,0x88,0x1c,0x8c,0x2f,0x24,0xc3,
0xc5,0x99,0x98,0x9c,0xec,0x57,0x9a,0x9b,0x94,0x5a,0x24,0xc1,0x0c,0x96,0x44,0x08,
0x08,0x29,0x70,0x71,0x27,0x17,0xa5,0x26,0x96,0xa4,0xa6,0xb8,0x24,0x96,0xa4,0x4a,
0xb0,0x80,0xe5,0x91,0x85,0x92,0xd8,0xc0,0x4e,0x32,0x06,0x04,0x00,0x00,0xff,0xff,
0x44,0x01,0xf8,0x14,0xa5,0x00,0
现在,我们将在Usersmartcontract中创建一个额外的数据字段financial。
typeUserstruct{
IDstring`json:"id"`
Emailstring`json:"email"`
Namestring`json:"name"`
Mobilestring`json:"mobile"`
Agestring`json:"age"`
Financialstring`json:"financial"`
}

Financial消息格式参考

financial:=&Financial{
ID:"F1",
BankName:"HellenicBank",
IFSCCode:"1234",
AccNumber:"8765",
CreatedDate:"12/12/08,
}

在将用户记录添加到分类帐时,还可以将financial消息格式添加到相同的Usersmartcontract中。

packagemain
import(
"fmt"
"log"
"github.com/golang/protobuf/proto"
)


funcmain(){
financial:=&Financial{
BankName:"HellenicBank",
IFSCCode:"1234",
AccNumber:"8765",
CreatedDate:"12/12/08,
}
financialdata,err:=proto.Marshal(financial)
iferr!=nil{
log.Fatal("marshalingerror:",err)
}


userdata:=&User{
ID:"1",
Email:"[email protected]",
Name:"James",
Mobile:"8765432",
Age:"34",
Financial:string(financialdata),
}


userDataJSONasBytes,err:=json.Marshal(userdata)


iferr!=nil{
returnshim.Error(err.Error())
}
indexName:="id"
userNameIndexKey,err:=stub.CreateCompositeKey(indexName,[]string{userdata.ID})


iferr!=nil{
returnshim.Error(err.Error())
}


err=stub.PutState(userNameIndexKey,userDataJSONasBytes)
iferr!=nil{
returnshim.Error(err.Error())

解析Protobuf


解析protobuf数据非常简单,因为它以字节的形式存储记录,可以使用Financialproto轻松地对其进行解析。

financialByteData,err:=proto.Marshal(financialData)
iferr!=nil{
log.Fatal("marshalingerror:",err)
}


//Parsingthefinancialbytedata
financial:=&Financial{}
err=proto.Unmarshal(financialByteData,financial)
iferr!=nil{
log.Fatal("unmarshalingerror:",err)
}


fmt.Println("BankName:"+financial.GetBankName())
fmt.Println("IFSCCode:"+financial.GetIfscCode())
fmt.Println("AccNumber:"+financial.GetAccNumber())
fmt.Println("CreatedDate:"+financial.GetCreatedDate()

总结


Protobuf简化了数据处理和格式化。它使用特殊生成的源代码来构造数据,从而实现在同一smartcontract中轻松写入和读取数据。

参考文献


1.https://developers.google.com/protocol-buffers

2.https://developers.google.com/protocol-buffers/docs/gotutorial

以上,就是在超级账本HyperledgerFabric中将Protobu用于到SmartContract的基本概述。

希望你能有所收获!

原文链接:https://hackernoon.com/what-is-protobuf-in-hyperledger-fabric-explained-gk7s32fz

本文为CSDN翻译,转载请注明出处。

更多精彩推荐

?完了!CPU一味求快出事儿了!|原力计划

?美国对华为出口管制升级;微信红包生成器App遭腾讯起诉;Python3.8.3发布|极客头条

?潘石屹Python考试成绩99分,网友:还有一分怕你骄傲

?发家致富靠AI?使用keras预测NBA比赛赚钱,回报率达136%……

?看完这篇操作系统,和面试官扯皮就没问题了!

?赠书|要解决区块链的可扩展性问题,有哪些可行的方法?

你点的每个“在看”,我都认真当成了喜欢

本文来源:区块链大本营
原文标题:超级账本Hyperledger Fabric中的Protobuf到底是什么?

—-

编译者/作者:区块链大本营

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...