最近在币安 bsc 链上有一个很火的币叫babydoge
,目前还没有上主流交易所,而是在 bsc 链上的去中心化交易所 pancakeswap 上,所以作为程序员,我们就可以通过监控链上数据来监控整个这个币的买卖。
下面我们一步一步完成整个开发
我们从币安区块链浏览器中找到 babydoge 的合约地址: https://bscscan.com/token/0xc748673057861a797275CD8A068AbB95A902e8de
可以看出这是一个 ERC20 的合约,我们直接通过 bsc 官方节点构造一个 provider 开始监听 Transfer 事件
const provider = ethers.getDefaultProvider('https://bsc-dataseed.binance.org/'); const filter = { address: babydogeAddress, topics: [ethers.utils.id('Transfer(address,address,uint256)')], }; provider.on(filter, analyseTransferEvent);
这样就可以将所有的 Transfer 事件全部转移给 analyseTransferEvent
函数处理
我们可以从 event 事件中拿到本次交易的 hash 值,然后通过 provider 获取到完整的数据
async function analyseTransferEvent(event) { // 获取 transaction 详情 const res = await provider.getTransaction(event.transactionHash); if (res.to !== pancakeAddress) { // 可能是一笔普通转账,不是 pancake 交易 return; } }
同时,我们可以将不是来自 pancakeswap 的数据直接丢弃(普通转账类型)
然后是如何获取本次交易的类型(买 /卖)和交易 babydoge 数量,这里我们需要利用 babydoge 的 abi 生成一个数据解析器来解析 event 事件,babydoge 的 abi 信息可以直接从区块链浏览器中获取 https://bscscan.com/address/0xc748673057861a797275CD8A068AbB95A902e8de#code
代码如下
const babydogeInterface = new ethers.utils.Interface(babydogeAbi); // 解析 event const parsedEvent = babydogeInterface.parseLog(event); // 交易发起人 const address = res.from; // 买 /卖 const action = address === parsedEvent.args.from ? 'SELL' : 'BUY'; // 交易数量 去掉后 9 位( babydoge 有 9 位精度) const amount = Number(parsedEvent.args.value) / 1e9;
最后是最麻烦的怎么知道用户本次交易的资金是多少,价值多少美金,我分析了 pancakeswap 的源码,发现总有以下几种交易类型
最终我定下的代码策略是这样的
最终部分代码如下
async function analyseTransferEvent(event) { // 获取 transaction 详情 const res = await provider.getTransaction(event.transactionHash); if (res.to !== pancakeAddress) { // 可能是一笔普通转账,不是 pancake 交易 return; } // 解析 input 数据 const input = pancakeInterface.parseTransaction({ data: res.data, value: res.value }); // 解析 event const parsedEvent = babydogeInterface.parseLog(event); // 获取 transfer 事件的数据 from -> to, value const address = res.from; // 本次交易的总价值 let usdValue = 0; // 买 /卖 const action = address === parsedEvent.args.from ? 'SELL' : 'BUY'; // 交易数量 去掉后 9 位 const amount = Number(parsedEvent.args.value) / 1e9; if (!input.name.includes('swap')) { return; } if (input.name.includes('ETH')) { // swapExactETHForTokens // swapExactETHForTokensSupportingFeeOnTransferTokens // swapExactTokensForETH // swapExactETHForTokensSupportingFeeOnTransferTokens // 使用 bnb 交易的 4 个方法 let bnb; if (res.value > 0) { // 用 bnb 买 bnb = Number(res.value); } else { // 卖成了 wBNB 交易 bnb = Number(input.args.amountOutMin); } usdValue = (getBnbPrice() * bnb) / 1e18; } else { // 用其他货币买或者卖 const path = input.args.path.map((it) => it.toLowerCase()); let inAmount, outAmount; if (input.name.includes('swapExactTokensForTokens')) { inAmount = Number(input.args.amountIn); outAmount = Number(input.args.amountOutMin); } else if (input.name.includes('swapTokensForExactTokens')) { inAmount = Number(input.args.amountInMax); outAmount = Number(input.args.amountOut); } if (action === 'BUY' && wBnbAddress === path[0]) { // 使用 wBnb 购买 usdValue = (getBnbPrice() * inAmount) / 1e18; } else if (action === 'BUY' && usdAddress.includes(path[0])) { // 使用 busd 购买 usdValue = inAmount / 1e18; } else if (action === 'SELL' && usdAddress.includes(_.last(path))) { // 卖成 busd usdValue = outAmount / 1e18; } else { // 使用非标准代币,从币安网站爬虫算一下价格 usdValue = await usdValueFromBinance(event.transactionHash); if (!usdValue) { console.log(`价格爬虫失败`, event.transactionHash); return; } } } if (usdValue < 1) { // 忽略 1 美元以下的交易 return; } // 将数据存到数据库 ...... }
最终实现效果如下:
受到马斯克喊单的影响,babydoge 交易量巨增,代码运用 2 天积累了 14 万条交易数据
同时做了一些对大户数据的监控,查看大户倾向是买多还是卖多
telegram: @zhuozhongcao 微信:18801971372
1 Elmer 2021-07-08 22:07:05 +08:00 BabyDoge to the moon |