白金会在线即时到账:超级账本Hyperledger Fabric中的Protobuf到底是什么?

本文来源:http://www.2233033.com/www_39yst_com/

菲律宾申博娱乐登入,什么样的故事,让最初的伯乐和千里马,变为如今的情逾骨肉  缘起宿命  在香港香江岁月中有位传奇人物,人称陈伯。而这样的消息也被国外媒体屡屡引用,阿根廷媒体《pasionfutbol》就指出,特维斯已经不可能重回欧洲踢球,而前曼联球星很可能就是吴晓晖所说的惊喜。他说此举的目的是为了表达自己对空气污染的看法,为了和同龄人进行沟通。刘雁军说,而手术效果也是慢慢呈现出来的,一般一年之后会看出明显变化,两年内达到理想的体重状态。

对此,神田纱织在Facebook上无奈回应,“好想死,我到底对不起谁了?”看到妹子几乎被气崩溃,一些网友开始出面安慰,“网络有好就有坏,还是请姐姐加油!”但也有网友继续调侃道,“感觉你可以开修图班发家致富…技术真的很强大。二是加强生态环境保护和治理,持续实施大气、水、土壤污染防治行动计划,着力解决生态环境方面的突出问题。  而公寓无论买了几套,贷了几次款,只要还清了就不影响以后继续贷款买商住的房子。密涿高速的建成,也标志着长约近千公里的首都地区环线高速公路替代路线全线贯通,该线路将环绕整个北京,也被民间俗称为北京大外环或者北京“七环”。

此外,平时票价较高的景区在本次广马期间还有打折优惠。法院同时认定拼音商标“QIAODAN”及“qiaodan”未损害乔丹姓名权。南水北调通水之后,通过置换南水北调的来水,关闭自备井。  武汉钢铁(集团)公司原董事长邓崎琳涉嫌受贿一案,由最高人民检察院指定广东省人民检察院侦查终结后,移送广东省佛山市人民检察院审查起诉。

作者 |?Deeptiman Pattnaik

译者 | 火火酱,责编 | Carol

出品 |? 区块链大本营(blockchain_camp)

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

Chaincode和SmartContract

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

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

User(用户)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、电子邮件、姓名、移动电话、年龄等与个人用户记录相关的数据字段。同样,如果我们需要存储每位用户的财务记录,那么我们就需要另一种名为Financial的smartcontract。

Financial (金融)SmartContract

type?Financial?struct?{
????ID?????????????string?????????`json:"id"`
????BankName???????string?????????`json:"bankName"`
????IFSCCode???????string?????????`json:"ifscCode"`
????AccNumber??????string?????????`json:"accNumber"`
????CreatedDate????string?????????`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消息格式的字节结果直接调用到User SmartContract并完全删除Financial SmartContract。

Protobuf是如何运作的?

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

安装

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

$?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-compiler

$?sudo?apt??install?protobuf-compiler

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

示例

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

financial.proto

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

编译该proto文件,生成用于Financial消息格式的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.
var?_?=?proto.Marshal
var?_?=?fmt.Errorf
var?_?=?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)
}


var?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)?}


var?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消息格式参考

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

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

package?main
import?(
????"fmt"
????"log"
????"github.com/golang/protobuf/proto"
)


func?main()?{
????financial?:=?&Financial?{
??????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?:=?&User?{
??????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

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

financialByteData,?err?:=?proto.Marshal(financialData)
????if?err?!=?nil?{
???????log.Fatal("marshaling?error:?",?err)
????}


/Parsing?the?financial?byte?data
financial?:=?&Financial{}
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简化了数据处理和格式化。它使用特殊生成的源代码来构造数据,从而实现在同一smartcontract中轻松写入和读取数据。

参考文献

1.?/developers_google_com/protocol-buffers

2.?/developers_google_com/protocol-buffers/docs/gotutorial

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

希望你能有所收获!

原文链接:/hackernoon_com/what-is-protobuf-in-hyperledger-fabric-explained-gk7s32fz

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

更多精彩推荐
?完了!CPU 一味求快出事儿了!| 原力计划
?美国对华为出口管制升级;微信红包生成器App遭腾讯起诉;Python 3.8.3 发布 | 极客头条
?潘石屹 Python 考试成绩 99 分,网友:还有一分怕你骄傲
?发家致富靠 AI ?使用 keras 预测NBA比赛赚钱,回报率达136%……
?看完这篇操作系统,和面试官扯皮就没问题了!
?赠书 | 要解决区块链的可扩展性问题,有哪些可行的方法?
你点的每个“在看”,我都认真当成了喜欢
展开阅读全文

没有更多推荐了,菲律宾申博娱乐登入

??2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读

申博提款最快登入 申博游戏注册登入 申博游戏端登入 www.860msc.com 申博棋牌游戏直营网 申博开户登入
菲律宾太阳网上娱乐登入 www.988msc.com 申博真人娱乐登入 菲律宾太阳娱乐网址登入 申博网址 申博苹果手机下载
www.9646.com 申博开户登入 777老虎机支付宝充值 申博官网下载登入 电子游戏微信支付充值 申博下载中心直营网