我想在fabric chaincode中使用gRPC来实现跨链通信,而不是使用fabric SDK。但是当我在fabric-sample/test-network上调用chaincode函数时,总是出现错误。
Error: endorsement failure during invoke. response: status:500 message:"error in simulation: failed to execute transaction eb5e480bd4075a767f56ae263741ca0f5f19620ef88952e26b7f1952bdbe83cd: could not launch chaincode chaincode_1.2:d3f97f15a635e73d3de230c8e5899e5fb95a68cf897c03e19f9e4eeca7ca3fd5: chaincode registration failed: container exited with 2"
谁能告诉我是什么原因导致这个错误?我的chaincode有bug或者gRPC不能在chaincode函数中使用?
关于gRPC的chaincode:
func (s *SmartContract) begin(ctx contractapi.TransactionContextInterface) error {
server.Main()
return nil
}
func (s *SmartContract) client(ctx contractapi.TransactionContextInterface) error {
// client.Clientfunc is the client main function
client.Clientfunc(Xt, R, sign, m)
}
server.go
func Main() {
listen, err := net.Listen("tcp", ":9090")
if err != nil {
fmt.Printf("failed to listen: %v", err)
return
}
grpcServer := grpc.NewServer()
pb.RegisterSendServiceServer(grpcServer, &server{})
err2 := grpcServer.Serve(listen)
if err2 != nil {
fmt.Printf("failed to serve: %v", err2)
return
}
}
client.go
func Clientfunc(Xt *btcec.PublicKey, R *btcec.PublicKey, s *big.Int, m []byte) []byte {
conn, err := grpc.Dial("127.0.0.1:9090", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
client := pb.NewSendServiceClient(conn)
output := &pb.SignInput{
XtX: Xt.X().Int64(),
XtY: Xt.Y().Int64(),
M: m,
RX: R.X().Int64(),
RY: R.Y().Int64(),
S: s.Int64(),
}
resp, _ := client.Send(context.Background(), output)
return resp.GetM()
}
1条答案
按热度按时间6jjcrrmo1#
谁能告诉我是什么原因导致这个错误?
如Hyperledger Fabric v2.x/ Logging Control中所述,服务器日志可以告诉您导致error 500(内部服务器错误)的原因
取决于您如何运行它:
这可能是由于链代码中的问题(如gRPC代码中的错误),也可能是由于链代码运行的环境。
从您的代码中,您可以考虑在链码中 * 不 * 启动gRPC服务器(
server.Main()
)。Chaincode在Hyperledger Fabric网络中运行,并不意味着像独立应用程序那样处理网络通信。相反,您应该使gRPC服务器成为独立运行的单独服务,然后链代码可以根据需要与此服务进行通信。
另外,
client.Clientfunc()
函数似乎建立了一个gRPC连接,发送一个请求,并等待响应。这是一个同步操作,如果响应需要很长时间才能到达,则可能会出现问题。最好使用异步操作(即,在回调函数中发送请求并处理响应),以避免阻塞链代码的执行。而且...你不应该忽略来自
client.Send()
的错误;)请确保您的gRPC服务器不需要安全连接,否则
grpc.WithTransportCredentials(insecure.NewCredentials())
(没有SSL/TLS的不安全连接)将失败。通常,建议在Fabric客户端应用程序中处理与外部系统的通信(如通过gRPC),而不是在链代码本身中。
如果我只想使用链码而不是结构应用程序,是否有任何方法可以在不同渠道的组织之间进行通信?
不同渠道上的组织之间的通信可能很复杂,因为这是Hyperledger Fabric设计的一个基本方面,即channels彼此隔离以维护数据隐私。
您可以考虑:
请注意,这种方法有一个限制,即第二个函数调用与第一个函数调用不是同一个事务的一部分,因此如果第一个事务失败,它不能回滚。
*互操作解决方案:还有更先进的区块链互操作性解决方案,如Interledger Protocol(ILP),可以用于在不同的Fabric网络之间(甚至在完全不同类型的区块链网络之间)移动数据或资产。
然而,这些产品仍处于研究和开发阶段,可能尚未准备好投入生产使用。