You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 11:57:04