我使用geth在本地建立测试链。部署合约,创建了一个事件来产生日志 这是我的合约代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract GHS is ERC20 {
constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_)
{
_mint(msg.sender, 10000 * 10**18);
}
event TransactionLogged(address indexed sender, string indexed dataType, uint256 indexed time, string number);
// 添加交易记录,并更新最新记录索引
function addRecord(address _token,string memory _dataType,uint256 _time,string memory _number) public returns (bool) {
emit TransactionLogged(_token, _dataType,_time,_number);
return true;
}
}
这是我的前端代码
async initWeb3() {
if (window.ethereum) {
try {
await window.ethereum.request({method: 'eth_requestAccounts'});
window.ethereum.on("accountsChanged", async (accounts) => {
this.name = accounts[0] || '未连接';
await this.getUserInfo()
});
return new Web3(window.ethereum);
} catch (error) {
console.error("用户拒绝授权:", error);
return null;
}
} else {
alert("请安装 MetaMask!");
return null;
}
}
,
async getUserInfo() {
this.record = []
const accounts = await this.web3.eth.getAccounts()
this.contract.getPastEvents('TransactionLogged', {
filter: {
// sender: accounts[0],
fromBlock: 0, // 替换为合约部署的实际区块号
toBlock: 'latest'
}
}, (err, res) => {
console.log(err)
console.log(res)
}).then(res => {
console.log('res', res)
})
console.log(this.record)
},
我调用查询记录的方法的时候,只在数组内返回了一个对象,而我确信 我是触发了好几次事件的。 为了验证事件有没有触发,我添加了监听
this.contract.events.TransactionLogged({}, (res, event) => {
console.log('监听事件', res, event)
})
可以确定的是,合约的事件是触发了多次的。但是我getPastEvents就只能获取一条数据 另外我在测试的时候还发现了一个情况;事件有一个筛选条件就是 公钥 当我用两个公钥都触发了事件的时候;再次调用getPastEvents事件我只会获取到最后一次触发的公钥的日志; 而且我调用getPastEvents传sender来过滤第一次触发事件的公钥的时候他就返回空数组; 这一切都是在geth客户端启动的私链上运行的 我的web3js版本是 "web3": "^1.10.0"
而且触发事件使用的是metamask钱包