Hyperledger fabric的底层技术:protobuf

超级账本项目用了protobuf

不要小看这项技术,理解protobuf,对流畅地理解超级账本项目的代码有关键的影响。那些proto文件实际是超级账本项目的数据结构,而我们理解一个大型项目,往往从理解数据结构开始。

序列化技术是用于分布式系统的技术,才涉及网络传输;如果是原来的单机版在一个jvm中,直接通过句柄引用就可以了

所有的消息来往都是序列化的,那么序列化和工行dsr协议有什么不同吗?

  • 序列化技术其实传输的是活的对象,反序列化技术出来的东西一定是内存中运行的java对象;相反的,工行dsr协议传输的都是死的消息,我们需要事先定义每个dsr协议格式,接收端要根据dsr协议再定义一个java对象,这样就4个一模一样的东西,一是客户端的java对象,一个是客户端放置的dsr协议文本,一个是服务器端的java对象,一个是服务器端的dsr协议文本。相反ethereumj里面只有1个java对象,客户端和服务器端版本一致,则java对象就一个可以了,使用了序列化技术,就不需要单独定义dsr文件。因为java类文件本身也是结构化的。

  • 超级账本项目中,proto都在

./github.com/hyperledger/fabric/protos/

  • 另外还有ca

./github.com/hyperledger/fabric/membersrvc/protos/ca.proto

TCA

ECA

TLSCA

2017-10-28

在超级账本中使用序列化的动作:

  • .proto文件生成.go文件,

  • 同时在程序中序列及反序列化

示例代码:

func main() {   

    // 创建一个protobuf消息Test  

    test := &example.Test{  

    // 使用辅助函数设置域的值  

    Label: proto.String("hello"),  

    Type:  proto.Int32(17),  

    Optionalgroup: &example.Test_OptionalGroup {  

        RequiredField: proto.String("good bye"),  

        },  

    }  

    fmt.Printf("Label:%s Type:%d\n", test.GetLabel(), test.GetType())    

    *(test.Label) = "hello go"  

    *(test.Type) = 18  

    // 进行编码  

    data, err := proto.Marshal(test)   //protobuf是根据这个对象的java类描述序列化的

    if err != nil {  

        log.Fatal("marshaling error: ", err)  

    }   

    fmt.Printf("Binary Len:%d\n", len(data))  



    // 进行解码  

    newTest := &example.Test{}  

    err = proto.Unmarshal(data, newTest)   //protobuf不是自描述的,参数除了data还要对象

    if err != nil {  

        log.Fatal("unmarshaling error: ", err)  

    }  

    fmt.Printf("Label:%s Type:%d\n", test.GetLabel(), test.GetType())  



    // 测试结果  

    if test.GetLabel() != newTest.GetLabel() {  

        log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())  

    }  

}  

2017-10-29

protobuf的实现

实现上,protobuf使用CodedOutputStream实现序列化逻辑、CodedInputStream实现反序列化逻辑,他们都包含write/read基本类型和Message类型的方法,write方法中同时包含fieldNumber和value参数,在写入时先写入由fieldNumber和WireType组成的tag值(添加这个WireType类型信息是为了在对无法识别的字段编码时可以通过这个类型信息判断使用那种方式解析这个未知字段,所以这几种类型值即可)

protobuf对不同数据类型的处理

数据类型处理
可见不同类型处理不同,根据class文件定义序列化后,这个tag值非常重要,

tag中没有这个类字段的名称(不是string),而是fieldnumber,只是按位置类,所以protobuf不是自描述的,只是两边class结构对应上才行,不像xml和json很自描述,由此带来的一个问题是:protobuf是二进制数据,存储后无法和现有的检索引擎配合

不过json的解析和protobuf的类似,看来json的自描述用处不大,就是调试时候方便点。

语法上都要指定反序列化后到哪个对象

json代码:

err := json.Unmarshal(jsonBlob, &animals)

猜你喜欢

转载自blog.csdn.net/wxid2798226/article/details/78504864