深入解析fabric的peer命令(终篇)fabric-protos-go


title: 深入解析fabric的peer命令(终篇)fabric-protos-go
date: 2023/6/3 11:24
tags: fabric区块链
categories: 区块链

先发个结果:
在这里插入图片描述

那么,上文https://xiutuuu.cloud/2023/06/03/%E6%B7%B1%E5%85%A5%E8%A7%A3%E6%9E%90fabric%E7%9A%84peer%E5%91%BD%E4%BB%A43/

最后一句endorser.ProcessProposal(context.Background(),signedProposal)在fabric-protos-go包里都做了什么呢?

该方法在fabric-protos-go/peer/peer.pb.go文件里

1.peer.pb.go源码

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: peer/peer.proto

package peer

import (
	context "context"
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	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

func init() { proto.RegisterFile("peer/peer.proto", fileDescriptor_c302117fbb08ad42) }

var fileDescriptor_c302117fbb08ad42 = []byte{
	// 177 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x8f, 0xb1, 0x0a, 0xc2, 0x30,
	0x10, 0x86, 0x37, 0x91, 0x2c, 0x85, 0x0a, 0x22, 0xc5, 0xc9, 0xd9, 0xa6, 0xa0, 0x6f, 0xa0, 0x38,
	0x5b, 0xea, 0xe6, 0x22, 0x6d, 0x73, 0xa6, 0x81, 0x9a, 0x0b, 0x77, 0x75, 0xf0, 0xed, 0xa5, 0xbd,
	0x06, 0x74, 0x49, 0xe0, 0xfb, 0xbf, 0x3b, 0xee, 0x57, 0x49, 0x00, 0xa0, 0x62, 0x7c, 0x74, 0x20,
	0x1c, 0x30, 0x5d, 0x4c, 0x1f, 0x67, 0x2b, 0x09, 0x08, 0x03, 0x72, 0xdd, 0x4b, 0x98, 0x6d, 0xff,
	0xe0, 0x83, 0x80, 0x03, 0x7a, 0x06, 0x49, 0x0f, 0x57, 0xb5, 0xbc, 0x78, 0x83, 0xc4, 0x40, 0xe9,
	0x59, 0x25, 0x25, 0x61, 0x0b, 0xcc, 0xe5, 0x6c, 0xa7, 0x6b, 0xd1, 0x58, 0xdf, 0x9c, 0xf5, 0x60,
	0x22, 0xcf, 0x36, 0x91, 0x47, 0x52, 0xcd, 0x6b, 0x4f, 0x95, 0xda, 0x21, 0x59, 0xdd, 0x7d, 0x02,
	0x50, 0x0f, 0xc6, 0x02, 0xe9, 0x67, 0xdd, 0x90, 0x6b, 0xe3, 0xc4, 0x78, 0xce, 0x7d, 0x6f, 0xdd,
	0xd0, 0xbd, 0x1b, 0xdd, 0xe2, 0xab, 0xf8, 0x51, 0x0b, 0x51, 0x73, 0x51, 0x73, 0x8b, 0x53, 0xcb,
	0x46, 0xfa, 0x1d, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd5, 0x12, 0xef, 0x66, 0xf9, 0x00, 0x00,
	0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4

// EndorserClient is the client API for Endorser service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type EndorserClient interface {
	ProcessProposal(ctx context.Context, in *SignedProposal, opts ...grpc.CallOption) (*ProposalResponse, error)
}

type endorserClient struct {
	cc *grpc.ClientConn
}

func NewEndorserClient(cc *grpc.ClientConn) EndorserClient {
	return &endorserClient{cc}
}

func (c *endorserClient) ProcessProposal(ctx context.Context, in *SignedProposal, opts ...grpc.CallOption) (*ProposalResponse, error) {
	out := new(ProposalResponse)
	err := c.cc.Invoke(ctx, "/protos.Endorser/ProcessProposal", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// EndorserServer is the server API for Endorser service.
type EndorserServer interface {
	ProcessProposal(context.Context, *SignedProposal) (*ProposalResponse, error)
}

// UnimplementedEndorserServer can be embedded to have forward compatible implementations.
type UnimplementedEndorserServer struct {
}

func (*UnimplementedEndorserServer) ProcessProposal(ctx context.Context, req *SignedProposal) (*ProposalResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ProcessProposal not implemented")
}

func RegisterEndorserServer(s *grpc.Server, srv EndorserServer) {
	s.RegisterService(&_Endorser_serviceDesc, srv)
}

func _Endorser_ProcessProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SignedProposal)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(EndorserServer).ProcessProposal(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.Endorser/ProcessProposal",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(EndorserServer).ProcessProposal(ctx, req.(*SignedProposal))
	}
	return interceptor(ctx, in, info, handler)
}

var _Endorser_serviceDesc = grpc.ServiceDesc{
	ServiceName: "protos.Endorser",
	HandlerType: (*EndorserServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "ProcessProposal",
			Handler:    _Endorser_ProcessProposal_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "peer/peer.proto",
}

2.逐句分析一下func (c *endorserClient) ProcessProposal

func (c *endorserClient) ProcessProposal(ctx context.Context, in *SignedProposal, opts ...grpc.CallOption) (*ProposalResponse, error) {
	out := new(ProposalResponse)
	err := c.cc.Invoke(ctx, "/protos.Endorser/ProcessProposal", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

这段代码定义了一个名为ProcessProposal的方法,属于endorserClient结构体的接收者。

func (c *endorserClient) ProcessProposal(ctx context.Context, in *SignedProposal, opts ...grpc.CallOption) (*ProposalResponse, error) {

该方法接收三个参数:ctxcontext.Context类型,in*SignedProposal类型,opts为可变参数列表,其中的元素类型为grpc.CallOption

out := new(ProposalResponse)

创建了一个新的ProposalResponse结构体实例,并将其赋值给变量out

err := c.cc.Invoke(ctx, "/protos.Endorser/ProcessProposal", in, out, opts...)

调用c.cc.Invoke方法,该方法是endorserClient结构体中的一个成员方法。它接收ctx、调用的方法路径"/protos.Endorser/ProcessProposal"、输入参数in、输出参数outopts作为参数。

到了最后,fabric-protos-go包里也不过是一个EndorserClient的接口,那这个接口是sdk去实现的吗?

在fabric-sdk-java中确实找到了EndorserClient接口的实现

EndorserClient.java

class EndorserClient {
    private static final Config config = Config.getConfig();
    private static final Log logger = LogFactory.getLog(EndorserClient.class);
    private static final boolean IS_TRACE_LEVEL = logger.isTraceEnabled();

    //    private final String channelName;
//    private final String name;
//    private final String url;
    private ManagedChannel managedChannel;
    private EndorserGrpc.EndorserFutureStub futureStub;
    private DiscoveryGrpc.DiscoveryFutureStub discoveryFutureStub;
    private boolean shutdown = false;
    private final String toString;

    /**
     * Construct client for accessing Peer server using the existing channel.
     *
     * @param channelBuilder The ChannelBuilder to build the endorser client
     */
    EndorserClient(String channelName, String name, String url, ManagedChannelBuilder<?> channelBuilder) {
        managedChannel = channelBuilder.build();
        futureStub = EndorserGrpc.newFutureStub(managedChannel);
        discoveryFutureStub = DiscoveryGrpc.newFutureStub(managedChannel);
        toString = "EndorserClient{" + "id: " + config.getNextID() + ", channel: " + channelName + ", name:" + name + ", url: " + url + "}";
        logger.trace("Created " + toString());

    }
}

最后总结一下

在这里插入图片描述

sequenceDiagram
	Title peer chaincode invoke命令到底都干了什么
	participant Peer chaincode invoke指令
	participant EndorserClient接口
	participant sdk对EndorserClient接口的实现
	
	Note over Peer chaincode invoke指令 : 1.创建一个调用invoke示例
	Note over Peer chaincode invoke指令 : 2.生成一个链码提案prop
	Note over Peer chaincode invoke指令 : 3.获取一个签名过的提案signedProp
	Note over Peer chaincode invoke指令 : 4.调用EndorserClient接口的processProposals方法,传递背书客户端和签名的提案
	Peer chaincode invoke指令 ->> EndorserClient接口: gRPC请求
	EndorserClient接口 ->> sdk对EndorserClient接口的实现: 调用sdk
	sdk对EndorserClient接口的实现 ->> EndorserClient接口: response
	EndorserClient接口 ->> Peer chaincode invoke指令: response
	Note over Peer chaincode invoke指令 : 5.创建一个签名的交易env
	Note over Peer chaincode invoke指令 : 6.bc.Send(env)用广播客户端发送交易

完结撒花~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值