ethers.js中contract.filters返回值及topics相关技术疑问
关于ethers.js中contract.filters的两个疑问
在使用ethers.js的contract.filters函数时,参考示例代码如下:
abi = [ "event Transfer(address indexed src, address indexed dst, uint val)" ]; contract = new Contract(tokenAddress, abi, provider); // 列出所有从myAddress发起的代币转账 contract.filters.Transfer(myAddress) // 返回结果: // { // address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // topics: [ // '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', // '0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72' // ] // }
疑问1:返回值中topics数组内的每个字符串分别代表什么?它们是否是交易哈希?
topics里的内容不是交易哈希,每个元素的具体含义:
- 第一个字符串:事件签名的Keccak256哈希值。事件签名是把事件定义标准化后的字符串(比如这里的
Transfer(address,address,uint256),Solidity中uint等价于uint256),用Keccak256哈希后得到该值,作用是标识当前要过滤的目标事件类型。 - 第二个字符串:索引参数(
indexed修饰的参数)的标准化格式值。因为示例中src参数加了indexed,所以把myAddress填充为32字节固定长度(地址前补0)后得到该值,用来精准匹配从指定地址发起的转账事件。
补充:非indexed修饰的参数不会出现在topics数组中,而是被打包在事件的data字段里。
疑问2:事件的排序规则是什么?最新的事件是否会排在topics数组的首位?
首先明确:topics数组只是过滤器的匹配规则,和事件的时间/区块顺序完全无关。
当用该过滤器查询链上事件时,默认返回的事件列表是按区块高度从旧到新排序的——最早发生的事件排在前面,最新的事件排在后面。如果需要让最新事件在前,可以在查询时指定倒序遍历逻辑(比如ethers.js中调用getLogs时设置fromBlock为最新区块号、toBlock为起始区块号,或者对返回结果做倒序处理)。
内容的提问来源于stack exchange,提问作者bzpassersby
相关产品推荐
相关产品推荐

