如何使用web3.js按参数过滤智能合约触发的事件?
你遇到的问题由三个常见错误导致,依次修正即可生效:
步骤1:修正合约事件定义并重新部署
// 给需要过滤的id参数加上indexed修饰符,动态类型加indexed后会将其keccak256哈希存入topic event PaymentMade(string indexed id); function pay(string id) public payable { // 原有业务逻辑 emit PaymentMade(id); }
修改后必须重新部署合约,并且更新前端使用的ABI文件,否则修改不会生效。
步骤2:getPastEvents 接口正确写法
const targetId = "something"; // 替换为你要匹配的id值 const options = { filter: { // 过滤键名必须和事件定义的参数名完全一致,此处为id而非你之前写的value id: targetId }, fromBlock: 0, toBlock: 'latest' }; try { // 事件名必须和合约定义的大小写完全一致,合约中为PaymentMade,不是你之前写的paymentMade const result = await contract.getPastEvents('PaymentMade', options); console.log("匹配的历史事件:", result); } catch (error) { console.log("查询错误:", error); }
步骤3:web3.eth.subscribe 实时订阅正确写法
如果要订阅实时推送的匹配事件,需要手动构造topics数组,第二个参数传入目标id的keccak256哈希:
const targetId = "something"; // 计算PaymentMade事件的签名哈希,对应topics第一个元素 const eventSignature = web3.utils.keccak256("PaymentMade(string)"); // 计算目标id的keccak256哈希,对应indexed参数的topic const targetIdHash = web3.utils.keccak256(targetId); const subscription = web3.eth.subscribe('logs', { address: '0x123456......', // 替换为你的合约地址 topics: [eventSignature, targetIdHash] }, (error, result) => { if (!error) { console.log("收到匹配的实时事件:", result); } });
内容的提问来源于stack exchange,提问作者Kevvv
相关产品推荐
相关产品推荐

