Hyperledger Fabric 1.4中addContractListener无法监听合约事件问题
Hyperledger Fabric 1.4 合约事件监听无输出问题排查
问题背景
- 运行环境:Hyperledger Fabric 1.4,已在first-network示例网络部署fabcar合约
- 自定义改动:在链码逻辑中新增事件抛出代码
SetEvent("initLedger",[]byte{"test"}) - 异常现象:通过Node.js SDK编写监听代码后,控制台无任何事件相关输出,始终无法捕获目标事件
参考监听代码
//connect to Fabric Network, but starting a new gateway const gateway = new Gateway(); //use our config file, our peerIdentity, and our discovery options to connect to Fabric network. await gateway.connect(ccpPath, { wallet, identity: peerIdentity, discovery: { enabled: true, asLocalhost: true } }); console.log('gateway connect'); //connect to our channel that has been created on IBM Blockchain Platform const network = await gateway.getNetwork('mychannel'); //connect to our insurance contract that has been installed / instantiated on IBM Blockchain Platform const contract = await network.getContract('fabcar'); await contract.addContractListener('my-contract-listener', 'InitLedger', (err, event, blockNumber, transactionId, status) => { if (err) { console.error(err); return; } //convert event to something we can parse event = event.payload.toString(); event = JSON.parse(event) //where we output the TradeEvent console.log('************************ Start Trade Event *******************************************************'); console.log(`make: ${event.type}`); console.log(`model: ${event.ownerId}`); console.log(`colour: ${event.id}`); console.log(`owner: ${event.description}`); console.log(`Block Number: ${blockNumber} Transaction ID: ${transactionId} Status: ${status}`); console.log('************************ End Trade Event ************************************'); });
排查步骤(按优先级从高到低)
- 优先检查事件名大小写匹配问题
Fabric合约事件名严格大小写敏感,链码中定义的事件名是initLedger(首字母小写i),但SDK监听时传入的过滤名是InitLedger(首字母大写I),二者完全不匹配是最直接的原因,把监听代码里的事件名改成和链码里完全一致的initLedger即可。 - 确认事件触发时机符合监听逻辑
SDK注册的合约监听器默认只会接收注册成功之后新上链的交易产生的事件,不会自动回溯历史区块中已经存在的事件。如果是在链码实例化/升级(initLedger逻辑通常在这一步执行)完成后才启动监听程序,是收不到之前已经产生的事件的,需要在监听器注册成功后,重新调用一次会触发SetEvent("initLedger")逻辑的链码交易,才能验证监听效果。 - 确认链码版本部署正确
检查修改后的链码是否已经安装到所有背书节点,并且成功执行了instantiate/upgrade操作,确保节点上运行的是新增了事件抛出逻辑的新版本,而非旧版fabcar链码;可以查看对应peer节点、链码容器的运行日志,确认调用目标交易时,SetEvent逻辑确实被执行到,无运行时报错。 - 检查SDK连接与进程保活配置
确认连接配置中discovery.asLocalhost = true和部署环境匹配,如果first-network部署在虚拟机/服务器而非本地,需要把该参数改为false,同时确认SDK可以正常访问peer节点的事件服务端口,无网络策略、防火墙拦截;监听器注册完成后要保持Node.js进程持续运行,不要让代码执行完直接退出,可以加一个长轮询逻辑或者阻塞语句避免进程退出,否则监听器还没收到事件进程就终止了。 - 修复事件payload解析逻辑
链码中抛出事件时传入的payload是[]byte{"test"},不是标准JSON格式,现有代码中直接调用JSON.parse(event)会抛出语法错误,就算收到事件也会被err分支拦截,建议调试阶段先注释掉JSON解析逻辑,直接打印原始payload字符串确认事件能正常接收,再根据实际payload格式调整解析代码。
内容的提问来源于stack exchange,提问作者Blockchain reader
相关产品推荐
相关产品推荐

