通过程序监控pancakeswap中babydoge的交易数据

项目出发点

最近在币安bsc链上有一个很火的币叫babydoge,目前还没有上主流交易所,而是在bsc链上的去中心化交易所 pancakeswap 上,所以作为程序员,我们就可以通过监控链上数据来监控...

## 项目出发点 最近在币安bsc链上有一个很火的币叫`babydoge`,目前还没有上主流交易所,而是在bsc链上的去中心化交易所 pancakeswap 上,所以作为程序员,我们就可以通过监控链上数据来监控整个这个币的买卖。 ## 开发思路 * 监控 babydoge 合约的 Transfer 事件 * 查询这个 Transfer 事件所对应的 Transaction 是否来自于 PancakeSwap,如果不是说明本次只是一次普通的转账,直接丢弃即可 * 如果是,下一步就是算出本次买/卖了多少个 babydoge,对应的资产价值是多少USDT(美元) * 将结果存入数据库做实时分析监控 下面我们一步一步完成整个开发 ### 1、开发环境 * 开发语言为 Javascript + Node.js * 通过 ethers.js 和链交互 * 使用 express.js 做http服务器 * 使用 prisma 作为 orm 和数据库交互(我使用的postgresql) ### 2、监控 Transfer 事件 我们从币安区块链浏览器中找到 babydoge 的合约地址: [**https://****bscscan.com/token/0xc74****8673057861a797275CD8A068AbB95A902e8de**](https://link.zhihu.com/?target=https%3A//bscscan.com/token/0xc748673057861a797275CD8A068AbB95A902e8de) 可以看出这是一个ERC20的合约,我们直接通过bsc官方节点构造一个provider开始监听Transfer事件 ```text 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` 函数处理 ### 3、获取本次交易的相关数据 我们可以从event事件中拿到本次交易的hash值,然后通过 provider 获取到完整的数据 ```text 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/0xc****748673057861a797275CD8A068AbB95A902e8de#code**](https://link.zhihu.com/?target=https%3A//bscscan.com/address/0xc748673057861a797275CD8A068AbB95A902e8de%23code) 代码如下 ```text 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的源码,发现总有以下几种交易类型 * 用 BNB 和 babydoge 交易 * 用 wBNB 和 babydoge 交易 * 用 美元类代币(BUSD, BSC-USD) 和 babydoge 交易 * 用 其他不知道ERC20币,通过BNB/BUSD中转,和Babydoge交易 最终我定下的代码策略是这样的 * 对于 BNB 或者 wBNB 代币交易,直接乘以bnb价格即可(通过爬虫维护一个bnb的实时价格 [**https://****bscscan.com/**](https://link.zhihu.com/?target=https%3A//bscscan.com/) 从这个网站左上角就有) * 对于使用美元代币的交易,直接拿到数量即可 * 对于使用其他ERC20代币的交易,我们直接bsc官方浏览器通过爬虫爬取本次的价格(这种交易比例低) 最终部分代码如下 ```text 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; } // 将数据存到数据库 ..... ``` 最终实现效果如下: ![](https://pic3.zhimg.com/80/v2-022011cc6e31fa847444bc43ef60ce7a_1440w.jpg) 受到马斯克喊单的影响,babydoge交易量巨增,代码运用2天积累了14万条交易数据 ![](https://pic3.zhimg.com/80/v2-49e6f72120960f6bf26b6a7e8a9fb762_1440w.jpg) 同时做了一些对大户数据的监控,查看大户倾向是买多还是卖多 ## 联系作者 微信:18801971372

项目出发点

最近在币安bsc链上有一个很火的币叫babydoge,目前还没有上主流交易所,而是在bsc链上的去中心化交易所 pancakeswap 上,所以作为程序员,我们就可以通过监控链上数据来监控整个这个币的买卖。

开发思路

  • 监控 babydoge 合约的 Transfer 事件
  • 查询这个 Transfer 事件所对应的 Transaction 是否来自于 PancakeSwap,如果不是说明本次只是一次普通的转账,直接丢弃即可
  • 如果是,下一步就是算出本次买/卖了多少个 babydoge,对应的资产价值是多少USDT(美元)
  • 将结果存入数据库做实时分析监控

下面我们一步一步完成整个开发

1、开发环境

  • 开发语言为 Javascript + Node.js
  • 通过 ethers.js 和链交互
  • 使用 express.js 做http服务器
  • 使用 prisma 作为 orm 和数据库交互(我使用的postgresql)

2、监控 Transfer 事件

我们从币安区块链浏览器中找到 babydoge 的合约地址:

https://**bscscan.com/token/0xc74**8673057861a797275CD8A068AbB95A902e8de

可以看出这是一个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 函数处理

3、获取本次交易的相关数据

我们可以从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/0xc**748673057861a797275CD8A068AbB95A902e8de#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的源码,发现总有以下几种交易类型

  • 用 BNB 和 babydoge 交易
  • 用 wBNB 和 babydoge 交易
  • 用 美元类代币(BUSD, BSC-USD) 和 babydoge 交易
  • 用 其他不知道ERC20币,通过BNB/BUSD中转,和Babydoge交易

最终我定下的代码策略是这样的

  • 对于 BNB 或者 wBNB 代币交易,直接乘以bnb价格即可(通过爬虫维护一个bnb的实时价格 https://**bscscan.com/** 从这个网站左上角就有)
  • 对于使用美元代币的交易,直接拿到数量即可
  • 对于使用其他ERC20代币的交易,我们直接bsc官方浏览器通过爬虫爬取本次的价格(这种交易比例低)

最终部分代码如下

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 &lt; 1) {
        // 忽略1美元以下的交易
        return;
    }

    // 将数据存到数据库
    .....

最终实现效果如下:

受到马斯克喊单的影响,babydoge交易量巨增,代码运用2天积累了14万条交易数据

同时做了一些对大户数据的监控,查看大户倾向是买多还是卖多

联系作者

微信:18801971372

  • 发表于 2021-07-02 22:53
  • 阅读 ( 1334 )
  • 学分 ( 2 )

评论