9.事件过滤


文档摘要

title: 9. 事件过滤 tags: ethers javascript event filter frontend web Ethers极简入门: 9. 事件过滤 我最近在重新学 ,巩固一下细节,也写一个 ,供小白们使用。 推特:@0xAAScience WTF Academy社群: 官网 wtf.academy | WTF Solidity教程 | discord | 微信群申请 所有代码和教程开源在github: github.com/WTFAcademy/WTFEthers 在上一讲 Ethers极简入门: 8. 合约监听 的基础上,我们拓展一下,在监听的过程中增加过滤器,监听指定地址的转入转出。 具体可参考ethers.js文档。

title: 9. 事件过滤 tags: - ethers - javascript - event - filter - frontend - web

Ethers极简入门: 9. 事件过滤

我最近在重新学ethers.js,巩固一下细节,也写一个WTF Ethers极简入门,供小白们使用。

推特@0xAA_Science

WTF Academy社群: 官网 wtf.academy | WTF Solidity教程 | discord | 微信群申请

所有代码和教程开源在github: github.com/WTFAcademy/WTFEthers

在上一讲 Ethers极简入门: 8. 合约监听 的基础上,我们拓展一下,在监听的过程中增加过滤器,监听指定地址的转入转出。

具体可参考ethers.js文档

过滤器

当合约创建日志(释放事件)时,它最多可以包含[4]条数据作为索引(indexed)。索引数据经过哈希处理并包含在布隆过滤器中,这是一种允许有效过滤的数据结构。因此,一个事件过滤器最多包含4个主题集,每个主题集是个条件,用于筛选目标事件。规则:

  • 如果一个主题集为null,则该位置的日志主题不会被过滤,任何值都匹配。
  • 如果主题集是单个值,则该位置的日志主题必须与该值匹配。
  • 如果主题集是数组,则该位置的日志主题至少与数组中其中一个匹配。

过滤器规则

构建过滤器

ethers.js中的合约类提供了contract.filters来简化过滤器的创建:

const filter = contract.filters.EVENT_NAME( ...args )

其中EVENT_NAME为要过滤的事件名,..args为主题集/条件。前面的规则有一点抽象,下面举几个例子。

  1. 过滤来自myAddress地址的Transfer事件
contract.filters.Transfer(myAddress)
  1. 过滤所有发给 myAddress地址的Transfer事件
contract.filters.Transfer(null, myAddress)
  1. 过滤所有从 myAddress发给otherAddressTransfer事件
contract.filters.Transfer(myAddress, otherAddress)
  1. 过滤所有发给myAddressotherAddressTransfer事件
contract.filters.Transfer(null, [ myAddress, otherAddress ])

监听交易所的USDT转账

  1. 从币安交易所转出USDT的交易

监听USDT合约之前,我们需要先看懂交易日志Logs,包括事件的topicsdata。我们先找到一笔从币安交易所转出USDT的交易,然后通过hash在etherscan查它的详情:

交易哈希:0xab1f7b575600c4517a2e479e46e3af98a95ee84dd3f46824e02ff4618523fff5

etherscan 示意图

该交易做了一件事:从 binance14 (币安热钱包)向地址0x354de44bedba213d612e92d3248b899de17b0c58 转账2983.98USDT。

查看该事件日志Logs信息:

etherscan logs示意图

  • address:USDT合约地址
  • topics[0]:事件哈希,keccak256("Transfer(address,address,uint256)")
  • topics[1]:转出地址(币安交易所热钱包)。
  • topics[2] 转入地址。
  • data:转账数量。
  1. 创建providerabi,和USDT合约变量:
const provider = new ethers.JsonRpcProvider(ALCHEMY_MAINNET_URL); // 合约地址 const addressUSDT = '0xdac17f958d2ee523a2206206994597c13d831ec7' // 交易所地址 const accountBinance = '0x28C6c06298d514Db089934071355E5743bf21d60' // 构建ABI const abi = [ "event Transfer(address indexed from, address indexed to, uint value)", "function balanceOf(address) public view returns(uint)", ]; // 构建合约对象 const contractUSDT = new ethers.Contract(addressUSDT, abi, provider);
  1. 读取币安热钱包USDT余额。可以看到,当前币安热钱包有8亿多枚USDT
const balanceUSDT = await contractUSDT.balanceOf(accountBinance) console.log(`USDT余额: ${ethers.formatUnits(balanceUSDT,6)}\n`)

币安热钱包USDT余额

  1. 创建过滤器,监听USDT转入币安的事件。
// 2. 创建过滤器,监听转移USDT进交易所 console.log("\n2. 创建过滤器,监听USDT转进交易所") let filterBinanceIn = contractUSDT.filters.Transfer(null, accountBinance); console.log("过滤器详情:") console.log(filterBinanceIn); contractUSDT.on(filterBinanceIn, (res) => { console.log('---------监听USDT进入交易所--------'); console.log( `${res.args[0]} -> ${res.args[1]} ${ethers.formatUnits(res.args[2],6)}` ) })

监听转入币安的USDT交易

  1. 创建过滤器,监听USDT转出币安的交易。
// 3. 创建过滤器,监听交易所转出USDT let filterToBinanceOut = contractUSDT.filters.Transfer(accountBinance); console.log("\n3. 创建过滤器,监听USDT转出交易所") console.log("过滤器详情:") console.log(filterToBinanceOut); contractUSDT.on(filterToBinanceOut, (res) => { console.log('---------监听USDT转出交易所--------'); console.log( `${res.args[0]} -> ${res.args[1]} ${ethers.formatUnits(res.args[2],6)}` ) } );

监听转出币安的USDT交易

总结

这一讲,我们介绍了事件过滤器,并用它监听了与币安交易所热钱包相关的USDT交易。你可以用它监听任何你感兴趣的交易,发现smart money做了哪些新交易,NFT大佬冲了哪些新项目,等等。


作者与出处
原作者: WTFAcademy
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: WTFAcademy 转发
评论区 (0)
U