Hyperledger结构中的Protobuf是什么?

释放双眼,带上耳机,听听看~!
在本文中,我将解释如何使用protobuf在hyperledger fabric中序列化和构造数据。Protobuf简化了hyperledger结构中的数据处理和格式化。它使用专门生成的源代码来生成数据,使得在同一个智能合约中轻松地编写和读取数据。

智能合约

《deeptiman pattnaik translator》《Huohuo sauce》的作者,《Carol》区块链《camp》的编辑

在本文中,我将解释如何使用protobuf在hyperledger fabric中序列化和构造数据。Protobuf简化了hyperledger结构中的数据处理和格式化。它使用专门生成的源代码来生成数据,使得在同一个智能合约中轻松地编写和读取数据。

智能合约

链码和智能合约

在超账本结构中,链码是一个特定的程序,用于处理区块链网络参与者同意的核心业务逻辑。Hyperledger fabric还使用称为smartcontract的数据格式技术,该技术是为链码中的特定数据模集定义的。链代码可以有多组智能合约,这些合约控制不同数据模的事务逻辑。简而言之,smartcontract管理事务,而链码管理smartcontract的部署方式。

例如,如果我们需要在分类账中存储一些用户信息记录,我们需要一个smartcontract,它可以定义单个记录所需的数据字段。

用户智能合约

type User struct { 
     ID      string         `json:"id"` 
     Email    string         `json:"email"` 
     Name     string         `json:"name"` 
     Mobile   string         `json:"mobile"` 
     Age      string         `json:"age"` 
 }

在smartcontract中,有ID、email、name、mobile phone、age和其他与个人用户记录相关的数据字段。同样,如果我们需要存储每个用户的财务记录,我们需要另一个称为财务的智能合约。

金融智能合约

type Financial struct { 
     ID             string         `json:"id"` 
     BankName       string         `json:"bankName"` 
     IFSCCode       string         `json:"ifscCode"` 
     AccNumber      string         `json:"accNumber"` 
     CreatedDate    string         `json:"createdDate"` 
 }

这两个smartcontract将部署到链码中,并处理两个分类账状态(WorldState和区块链)的交易逻辑。

Smartcontract主要在world状态下执行put、get、delete和gethistory。

一。 ;putstate-为每个不同的键创建新对象,或覆盖现有对象。

2。 ;getstate–从分类帐状态中检索具有不同键的对象。

3 ;delstate-从分类帐的世界状态中删除对象。

四。 ;gethistoryforkey-返回跨时间键的所有事务历史记录。

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

智能合约

Protocol buffer(protobuf)是Google的序列化结构化数据,它独立于语言和平台,具有可扩展的机制。与传统的数据格式(如XML或JSON)相比,序列化的结构化数据是以字节为单位编译的,因此它更小、更快、更简单。

智能合约

为什么使用protobuf?

可见,用户和财务两个智能合约将信息存储在同一个用户账中,即用户存储用户的基本信息,财务存储用户银行账户的详细信息。

但是,如果我们从查询目的的角度来看待智能合约,那么这两个数据集之间就没有关系。我们不能为用户和财务数据模定义与密钥相同的ID,因为分类账数据存储在密钥-值对中,如果出现相同的密钥,则信息将被覆盖。

AMPL智能合约

这两个记录将以两个不同的ID存储在分类帐状态中

为了解决这个问题,protobuf提供了一个更快、更灵活的解决方案。我们只需要编写一个.Proto文件来描述数据结构,在这种情况下,我们要存储的财务数据结构。

结果,protobuf消息格式中的字节结果被直接调用给用户smartcontract,财务smartcontract被完全删除。

智能合约

protobuf是如何工作的?

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

安装

首先,我们需要遵循一定的安装过程来使用protobuf编译器。


go get github.com/golang/protobuf

go get github.com/golang/protobuf/proto

go get -u github.com/golang/protobuf/protoc-gen-go

export PATH=$PATH:$GOPATH/bin 
 
 

现在,安装protobuf编译器


sudo apt  install protobuf-compiler

然后,在命令行中键入protoc’应显示“缺少输入文件”,表示protobuf编译器已成功安装。

例子

首先,我们需要建立一个金融体系。原始文件。它由四个字段组成:银行名称、IFSC代码、帐号和创建日期。

financial.proto 
  
 syntax="proto3"; 
 package main; 
 message Financial { 
       string bankName = 1; 
       string ifscCode = 2; 
       string accNumber = 3; 
       string createdDate = 4; 
 } 
 
 
 

编译proto文件,生成财务信息格式的protobuf数据模文件。


protoc --go_out=. *.proto

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

financial.pb.go 
  
 // Code generated by protoc-gen-go. DO NOT EDIT. 
 // source: financial.proto 
 package main 
 import ( 
     fmt "fmt" 
     proto "github.com/golang/protobuf/proto" 
     math "math" 
 ) 
 // Reference imports to suppress errors if they are not otherwise used. 
 ar _ = proto.Marshal 
 ar _ = fmt.Errorf 
 ar _ = math.Inf 
 // This is a compile-time assertion to ensure that this generated file 
 // is compatible with the proto package it is being compiled against. 
 // A compilation error at this line likely means your copy of the 
 // proto package needs to be updated. 
 const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 
 type Financial struct { 
     BankName             string   `protobuf:"bytes,1,opt,name=bankName,proto3" json:"bankName,omitempty"` 
     IfscCode             string   `protobuf:"bytes,2,opt,name=ifscCode,proto3" json:"ifscCode,omitempty"` 
     AccNumber            string   `protobuf:"bytes,3,opt,name=accNumber,proto3" json:"accNumber,omitempty"` 
     CreatedDate          string   `protobuf:"bytes,4,opt,name=createdDate,proto3" json:"createdDate,omitempty"` 
     XXX_NoUnkeyedLiteral struct{} `json:"-"` 
     XXX_unrecognized     []byte   `json:"-"` 
     XXX_sizecache        int32    `json:"-"` 
 } 
  
  
 func (m *Financial) Reset()         { *m = Financial{} } 
 func (m *Financial) String() string { return proto.CompactTextString(m) } 
 func (*Financial) ProtoMessage()    { 
  
 func (*Financial) Descriptor() ([]byte, []int) { 
     return fileDescriptor_a283ebe7677acfbc, []int{0} 
 } 
  
  
 func (m *Financial) XXX_Unmarshal(b []byte) error { 
     return xxx_messageInfo_Financial.Unmarshal(m, b) 
 } 
  
  
 func (m *Financial) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 
     return xxx_messageInfo_Financial.Marshal(b, m, deterministic) 
 } 
  
  
 func (m *Financial) XXX_Merge(src proto.Message) { 
     xxx_messageInfo_Financial.Merge(m, src) 
 } 
  
  
 func (m *Financial) XXX_Size() int { 
     return xxx_messageInfo_Financial.Size(m) 
 } 
  
  
 func (m *Financial) XXX_DiscardUnknown() { 
     xxx_messageInfo_Financial.DiscardUnknown(m) 
 } 
  
  
 ar xxx_messageInfo_Financial proto.InternalMessageInfo 
 func (m *Financial) GetBankName() string { 
     if m != nil { 
            return m.BankName 
     } 
     return "" 
 } 
  
  
 func (m *Financial) GetIfscCode() string { 
     if m != nil { 
            return m.IfscCode 
     } 
     return "" 
 } 
  
  
 func (m *Financial) GetAccNumber() string { 
     if m != nil { 
            return m.AccNumber 
     } 
     return "" 
 } 
  
  
 func (m *Financial) GetCreatedDate() string { 
     if m != nil { 
            return m.CreatedDate 
     } 
     return "" 
 } 
  
  
 func init() { 
     proto.RegisterType((*Financial)(nil), "main.Financial") 
 } 
  
  
 func init() { proto.RegisterFile("financial.proto", fileDescriptor_a283ebe7677acfbc) } 
  
  
 ar fileDescriptor_a283ebe7677acfbc = []byte{ 
     // 136 bytes of a gzipped FileDescriptorProto 
     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 
 现在,我们将在User smartcontract中创建一个额外的数据字段financial。 
 type User struct { 
     ID             string         `json:"id"` 
     Email          string         `json:"email"` 
     Name           string         `json:"name"` 
     Mobile         string         `json:"mobile"` 
     Age            string         `json:"age"` 
     Financial      string         `json:"financial"` 
 } 
 

财务信息格式见

financial := AMPLFinancial { 
      ID:           "F1", 
      BankName:     "Hellenic Bank", 
      IFSCCode:     "1234", 
      AccNumber:    "8765", 
      CreatedDate : "12/12/08, 
 }

将用户记录添加到分类账时,还可以将财务消息格式添加到同一用户智能合约。

package main 
 import ( 
     "fmt" 
     "log" 
     "github.com/golang/protobuf/proto" 
 ) 
  
  
 func main() { 
     financial := AMPLFinancial { 
       BankName:        "Hellenic Bank", 
       IFSCCode:        "1234", 
       AccNumber:   "8765", 
       CreatedDate : "12/12/08, 
     } 
      financialdata, err := proto.Marshal(financial) 
      if err != nil { 
         log.Fatal("marshaling error: ", err) 
      } 
  
  
     userdata := AMPLUser { 
       ID:       "1", 
       Email:         "james@example.com", 
       Name:       "James", 
       Mobile:     "8765432", 
       Age:       "34", 
       Financial:  string(financialdata), 
      } 
  
  
       userDataJSONasBytes, err := json.Marshal(userdata) 
  
  
       if err != nil { 
         return shim.Error(err.Error()) 
       } 
       indexName := "id" 
       userNameIndexKey, err := stub.CreateCompositeKey(indexName, []string{userdata.ID}) 
  
  
       if err != nil { 
         return shim.Error(err.Error()) 
       } 
  
  
       err = stub.PutState(userNameIndexKey, userDataJSONasBytes) 
       if err != nil { 
         return shim.Error(err.Error())

原机分析

解析protobuf数据非常简单,因为它以字节为单位存储记录,使用financial proto可以轻松解析这些记录。

financialByteData, err := proto.Marshal(financialData) 
     if err != nil { 
        log.Fatal("marshaling error: ", err) 
     } 
  
  
 //Parsing the financial byte data 
 financial := AMPLFinancial{} 
 err = proto.Unmarshal(financialByteData, financial) 
     if err != nil { 
         log.Fatal("unmarshaling error: ", err) 
     } 
  
  
 fmt.Println("BankName : "+financial.GetBankName()) 
 fmt.Println("IFSCCode : "+financial.GetIfscCode()) 
 fmt.Println("AccNumber : "+financial.GetAccNumber()) 
 fmt.Println("CreatedDate : "+financial.GetCreatedDate()

智能合约

总结

Protobuf简化了数据处理和格式化。它使用特殊生成的源代码来构造数据,这使得在同一个智能合约中轻松地编写和读取数据。

智能合约

参考

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

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

以上是在hyperledger fabric中使用protobu到smartcontract的基本概述。

希望你能有所收获!

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

这是CSDN的翻译。请注明转载来源。

人已赞赏
头条

今日推荐的美元负溢价背后:比特币定价权正在转移

2020-5-18 21:06:18

头条

工业和信息化部:加快“新基础设施建设”步伐推进数字化转型

2020-5-18 22:57:19

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索