使用@hyperledger/fabric-gateway遇EndorseError及Network/Contract为空问题
首先澄清:你看到的NetworkImpl {}和ContractImpl {}是正常现象,不是对象为空。Hyperledger Fabric Gateway的这两个类使用了ES私有字段(以#开头),Node.js的console.log默认不会输出私有属性,所以看起来是空对象,但实际实例已经正确创建,和后续的DNS解析错误无关。
核心错误原因:gRPC连接配置错误
真正的问题是EndorseError: 14 UNAVAILABLE: Name resolution failed for target dns:grpcs://localhost:9051,这个错误由以下几个配置问题导致:
1. TLS CA证书未正确读取
你的连接配置文件中,tlsCACerts.pem是证书文件的路径,但你直接用Buffer.from(ccp.peers[...].tlsCACerts.pem)把路径字符串转成了Buffer,而不是读取文件中的证书内容。这会导致gRPC无法验证Peer的TLS证书,进而引发连接失败。
2. Peer URL格式错误
gRPC-js的Client构造函数不需要在URL中带grpcs://前缀,该前缀会干扰DNS解析逻辑,应该只保留主机:端口的格式。
3. Peer选择逻辑错误
你用${userName}.${org}.evidence-vault.com作为Peer的key,但连接配置文件中的Peer key是FD100.forensic.evidence-vault.com这类固定名称,并非用户名拼接格式。如果你的用户名不是FD100/FD101,这里会获取到undefined的Peer配置。
修复步骤与代码示例
修复getClient函数
const fs = require('fs'); const grpc = require('@grpc/grpc-js'); const getClient = async (ccp, org) => { // 从组织配置中获取第一个可用Peer const orgConfig = ccp.organizations[org]; if (!orgConfig || orgConfig.peers.length === 0) { throw new Error(`组织${org}没有配置Peer`); } const peerName = orgConfig.peers[0]; const peerConfig = ccp.peers[peerName]; // 读取TLS CA证书文件的实际内容 const tlsCertBuffer = fs.readFileSync(peerConfig.tlsCACerts.pem); const tlsCredentials = grpc.credentials.createSsl(tlsCertBuffer); // 移除grpcs://前缀,保留主机:端口格式 const peerUrl = peerConfig.url.replace('grpcs://', ''); return new grpc.Client(peerUrl, tlsCredentials, { 'grpc.ssl_target_name_override': peerConfig.grpcOptions['ssl-target-name-override'], }); };
调整getContractObject中的调用
把client = await getClient(ccp, userName, org);改为:
client = await getClient(ccp, org);
额外检查项
- 确认Peer服务正在运行,端口9051(或10051)已正确映射到本地。
- 验证连接配置文件中的
ssl-target-name-override与Peer证书的CN字段完全匹配(当前配置是正确的,为FD100.forensic.evidence-vault.com)。 - 确保证书文件路径正确,文件权限允许读取。
内容的提问来源于stack exchange,提问作者Kshitij Sonawane

