BSC Spider - 用代码发现币安BSC的流行项目【含源码】

币安智能链逐渐成为DeFi的一片热土,越来越多的项目从以太坊移植到币安BSC平台。 在这个教程中,我们将学习如何开发一个应用Bsc Spider来尝试发现币安BSC上交易活跃的BEP20代币, 从而帮助我们更好地洞察币安BSC上的DeFi活动。

用自己熟悉的语言学习 以太坊开发Java | Php | Python | .Net / C# | Golang | Node.JS | Flutter / Dart

1、Bsc Spider原理概述

如你所知,DeFi运动的基础是代币,无论是以太坊DeFi中的ERC20代币,还是BSC Defi 中的BEP20代币,都是承载各种DeFi协议的基础媒介。因此,通过观察BSC上的BEP20的 交易,我们就可以直观地了解哪些DeFi项目是真正受欢迎的。

BEP20和ERC20一样,在转账时都会触发一个事件,其原型定义如下:

1
Transfer(address from, address to, uint value);

因此,我们只要从BSC链上提取一定周期发生内的BEP20代币的Transfer事件并按照代币 合约地址进行分类统计,就可以知道在这个周期中的各种DeFi项目的真实活跃情况了。

在进入实际代码之前,让我们先看一下要使用的开发工具:

  • Node.js:基础运行环境,提供js运行时,在这个教程中,我们使用 Node 12 LTS版本
  • ethers.js:轻量的js版本的web3访问库,在这个教程中,我们使用 Ethers.js 5.0 版本

BEP20一键发币工具:BSC TokenDIY

2、创建Bsc Spider项目

首先创建一个新的目录 bscspider,然后进入该目录执行如下命令初始化:

1
2
~$ mkdir bscspider && cd bscspider
~/bscspider$ npm init -y

输出结果类似下面这样:

接下来安装我们要用到的主要工具ethers.js:

1
npm install --save ethers

输出结果如下:

接下来我们就可以着手代码的编写了。

3、编写Bsc Spider代码框架

用你喜欢的编辑器打开index.js文件,复制如下代码:

1
2
3
4
5
6
7
const { ethers }  = require('ethers')

async function main(){} // todo

main()
.then(() => console.log('done'))
.catch(e => console.error(e))

在上面的代码中,我们首先引入ethers库,然后声明一个异步函数main, 注意这里我们还没有实现main()函数,只是占位,在代码的最后,我们 调用main()函数并恰当地捕捉异常。

4、Bsc Spider:抓取最新区块的Transfer事件

要抓取最新区块的Transfer事件,首先需要创建一个Ethers的Provider对象:

1
const provider = new ethers.providers.JsonRpcProvider('https://bsc-dataseed1.binance.org')

当然如果你有自己的BSC节点,也可以把你的URL传入JsonRpcProvider构造函数,我们这里 简单地使用币安官方提供的节点URL。

在Ethers中,Provider对象是一个EventEmitter,当发现新的合约事件时,就会 触发我们提供的监听函数。不过我们首先需要定义一个filter对象来声明感兴趣的事件:

1
2
3
4
5
const filter = {
topics: [
ethers.utils.id('Transfer(address,address,uint256)')
]
}

接下来就可以监听了。我们只对合约地址感兴趣,因此每当看到一个合约地址, 就意味着这个合约发生了一次转账交易,简单地累加交易并记录在哈希表counter中 就可以了:

1
2
3
4
5
const counter = {}
provider.on(filter, async log => {
if(!counter[log.address]) counter[log.address] = 1
else counter[log.address] += 1
}

下面就是抓取并处理最新区块的Transfer事件的代码完成后main()函数的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async function main(){
const provider = new ethers.providers.JsonRpcProvider('https://bsc-dataseed1.binance.org')
const filter = {
topics: [
ethers.utils.id('Transfer(address,address,uint256)')
]
}
const counter = {}
provider.on(filter, async log => {
if(!counter[log.address]) counter[log.address] = 1
else counter[log.address] += 1
}

}

5、Bsc Spider:定时转储BEP20交易统计数据

为了便于后续分析,我们需要将counter记录的数据定时转储到磁盘文件,因此用 一个1分钟的定时器来完成这一操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const fs = require('fs')

const t1 = Date.now()
setInterval(async () => {
const lines = []
for(let addr in counter){
const name = await getTokenName(addr)
lines.push([addr, name, counter[addr]])
}
lines.sort((a, b) => b[1] - a[1] )
fs.writeFile('./counter.csv', lines.join('\n'))
const elapsed = (Date.now() - t1 ) / (60*1000)
console.log(`saved after ${elapsed} minutes, tokens: ${lines.length}`)
}, 60000)

在上面的代码中,我们使用getTokenName()函数来获取代币名称,以便记录到转出 的CSV文件中,其代码如下:

1
2
3
4
5
async function getTokenName(address){
const abi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]
const token = new ethers.Contract(address, abi, provider)
return await token.name()
}

6、完整的Bsc Spider代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const { ethers }  = require('ethers')
const fs = require('fs')


async function main(){
const provider = new ethers.providers.JsonRpcProvider('https://bsc-dataseed1.binance.org')
const filter = {
topics: [
ethers.utils.id('Transfer(address,address,uint256)')
]
}
const counter = {}
provider.on(filter, async log => {
if(!counter[log.address]) counter[log.address] = 1
else counter[log.address] += 1
}

async function getTokenName(address){
const abi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]
const token = new ethers.Contract(address, abi, provider)
return await token.name()
}

const t1 = Date.now()
setInterval(async () => {
const lines = []
for(let addr in counter){
const name = await getTokenName(addr)
lines.push([addr, name, counter[addr]])
}
lines.sort((a, b) => b[1] - a[1] )
fs.writeFile('./counter.csv', lines.join('\n'))
const elapsed = (Date.now() - t1 ) / (60*1000)
console.log(`saved after ${elapsed} minutes, tokens: ${lines.length}`)
}, 60000)
}

main()
.then(() => console.log('done'))
.catch(e => console.error(e))

7、分析Bsc Spider的转储数据

最简单的方法是用Excel来打开转储的CSV文件,看起来是这样:

然后利用excel的数据分析功能。例如绘制最活跃的50种代币:

是不是和你想的一样?

8、Bsc Spider开发教程结束语

在这个教程中,我们学习了如何使用ethers.js来跟踪BSC上最受欢迎的BEP20代币。这 只是一个教学代码,其中还有很多可以改进的环节,欢迎你继续深入思考改进或者微信交流:


汇智网原创,转载请标明出处