Hyperledger Fabric v2.5新Gateway Client API如何查询区块与交易信息?
Hyperledger Fabric Gateway v1.x中通道查询方法的替代方案
功能移除的原因
新的Fabric Gateway Client API(v1.x)是针对Fabric v2.4+的Gateway服务架构重新设计的,核心目标是简化链码交互流程,让开发者无需关注底层通道、Peer等组件的复杂细节。旧SDK中getChannel()提供的通道级查询(如按ID查区块、交易)属于底层网络管理能力,不在新网关API的核心职责范围内,因此被移除,以保证API的简洁性和聚焦性。
替代实现方案
方案1:结合Fabric Java SDK补充底层查询
可以在项目中同时引入新网关SDK和兼容版本的Fabric Java SDK(建议使用与Fabric网络版本一致的2.5.x版本),利用新网关的身份信息初始化Channel对象,执行通道查询:
// 从已创建的Gateway获取身份 Identity gatewayIdentity = gateway.getIdentity(); // 初始化Fabric Java SDK的客户端上下文 ClientContext clientContext = ClientContext.newInstance() .setIdentity(gatewayIdentity) .setTlsCertificates(/* 传入TLS证书 */) .build(); // 创建并初始化Channel Channel channel = clientContext.newChannel("mychannel"); // 添加目标Peer(需配置Peer地址和TLS信息) Peer peer = Peer.createNewInstance( "peer0.org1.example.com", "grpcs://peer0.org1.example.com:7051", clientContext.getTlsCertificates() ); channel.addPeer(peer); channel.initialize(); // 执行查询操作 BlockInfo blockInfo = channel.queryBlockByTransactionID(txID); TransactionInfo txInfo = channel.queryTransactionByID(txID);
方案2:直接调用Peer的gRPC API
新网关SDK底层基于gRPC,可通过网关的连接获取Peer的gRPC Stub,直接调用底层查询接口:
// 获取网关的gRPC通道 Gateway gateway = Gateway.create(gatewayOptions); ManagedChannel grpcChannel = gateway.getGrpcChannel(); // 创建Peer的gRPC阻塞Stub PeerGrpc.PeerBlockingStub peerStub = PeerGrpc.newBlockingStub(grpcChannel) .withCallCredentials(new FabricCallCredentials(gateway.getIdentity())); // 查询交易详情 QueryTransactionRequest txRequest = QueryTransactionRequest.newBuilder() .setTransactionId(txID) .setChannelId("mychannel") .build(); QueryTransactionResponse txResponse = peerStub.queryTransaction(txRequest); TransactionEnvelope txEnvelope = txResponse.getTransactionEnvelope(); // 查询交易所在区块 QueryBlockByTxIDRequest blockRequest = QueryBlockByTxIDRequest.newBuilder() .setTransactionId(txID) .setChannelId("mychannel") .build(); QueryBlockByTxIDResponse blockResponse = peerStub.queryBlockByTxID(blockRequest); Block block = blockResponse.getBlock();
方案3:通过链码封装查询逻辑(推荐)
如果业务允许,建议在链码中封装区块、交易查询的逻辑,然后通过新网关SDK调用链码获取数据,这种方式更符合新网关的设计理念,无需直接操作底层网络组件:
// 示例Go链码中的查询方法 func (c *SmartContract) QueryTransactionByID(ctx contractapi.TransactionContextInterface, txID string) ([]byte, error) { txInfo, err := ctx.GetStub().GetTransactionByID(txID) if err != nil { return nil, fmt.Errorf("failed to get transaction: %v", err) } return txInfo, nil } func (c *SmartContract) QueryBlockByTxID(ctx contractapi.TransactionContextInterface, txID string) ([]byte, error) { block, err := ctx.GetStub().GetBlockByTxID(txID) if err != nil { return nil, fmt.Errorf("failed to get block: %v", err) } return json.Marshal(block) }
然后在Java客户端中调用:
Contract contract = network.getContract("mychaincode"); // 查询交易详情 byte[] txResult = contract.evaluateTransaction("QueryTransactionByID", txID); // 查询区块详情 byte[] blockResult = contract.evaluateTransaction("QueryBlockByTxID", txID);
内容的提问来源于stack exchange,提问作者gilvictor
相关产品推荐
相关产品推荐

