0%

eth | web3.js subscribe 「pending」

这里是 web3.js 订阅相关的知识。


参考资料



订阅方式


这里主要讲述两种订阅方式。

  • pendingTransactions
  • logs

这里以 bsc 为例, web3.js 是完美支持 fork eth 的链的。

pendingTransactions

代码如下

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
const Web3 = require("web3")
const provider = new Web3.providers.WebsocketProvider("wss://bsc.getblock.io/mainnet/?api_key=b32504***")
// const provider = new Web3.providers.WebsocketProvider("https://bsc.getblock.io/mainnet/?api_key=b32504***")

// 上面两个都可以,必须是 WebsocketProvider ,但是,推荐使用 wss
const web3 = new Web3(provider);
const check = (data) => {
console.log(data)
data = null
// 这句话必须要,要了之后,垃圾回收装置就会进行回收,不要的话,过段时间会撑爆内存
}

const check2 = async (data) => {
// 根据 tx 来获取数据
await web3.eth.getTransaction(data)
.then(async (data) => {
await check(data)
}).catch((reason => {
}));
}

web3.eth.subscribe("pendingTransactions", ((error, result) => {
})).on("data", async (data) => {
await check2(data)
})

对于 pendingTransactions 来讲,必须要做到能快速处理,不然,大量的数据过来,即便是到手后是 pending 但是,处理的时候,已经是进入区块的状态了。

所以,代码必须要进行异步处理,而不是同步。同时,将不用的值赋予 null ,以防止内存撑爆。

下面,我们来找到一个输出值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
blockHash: null,
blockNumber: null,
from: '0x2FCE9F84aeF6D6cf03EB44dAdF37F5B3B94e8FE4',
gas: 4000000,
gasPrice: '7000000000',
hash: '0x46ab3eda9ca611bbb839bab26b67425f38d577ede8fb350cc3b30b5431483acf',
input: '0x7ff36ab5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000002fce9f84aef6d6cf03eb44dadf37f5b3b94e8fe4000000000000000000000000000000000000000000000000000000006134e4870000000000000000000000000000000000000000000000000000000000000002000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c00000000000000000000000023662f3f9f35daab7a8d10654b5a4c1f3e57fc7a',
nonce: 304,
to: '0x10ED43C718714eb63d5aA57B78B54704E256024E',
transactionIndex: null,
value: '100000000000000000',
type: 0,
v: '0x94',
r: '0xab11345351a4e6045aa0bc4094edc5f068770b7064c3b65def740ffb8821c86b',
s: '0x189463a63ad620ce7ef9e839bf80f53e7da8e2bbaa4614b41f237c74fa01a8a5'
}

因为是 pending 状态,所以 blockHash 还有 blockNumber 都没有。

  • from
    • 哪个地址发出的
  • to
    • 发向哪个地址
  • gas
    • gas limit
  • gasprice
    • gas 单价
  • input
    • 调用了什么方法

我们在这里重点讲述一下 input

解析该 input 有两个方法

另外是,根据自身需要进行截取。

我们将 input 进行划分

1
2
3
4
5
6
7
8
MethodID: 0x7ff36ab5
[0]: 0000000000000000000000000000000000000000000000000000000000000000
[1]: 0000000000000000000000000000000000000000000000000000000000000080
[2]: 0000000000000000000000002fce9f84aef6d6cf03eb44dadf37f5b3b94e8fe4
[3]: 000000000000000000000000000000000000000000000000000000006134e487
[4]: 0000000000000000000000000000000000000000000000000000000000000002
[5]: 000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c
[6]: 00000000000000000000000023662f3f9f35daab7a8d10654b5a4c1f3e57fc7a

input 是按照 64 个字符进行一段段划分的。另外,input 的顺序和调用方法无关。「起码,我没找到关系」

调用的方法如下

Function: swapExactETHForTokens(uint256 amountOutMin, address[] path, address to, uint256 deadline)

从数据上可以看出 2from56 分别是 bnb 的合约地址,还有 fts 的合约地址。

如果进行字段截取解析是可以进行对应的,而这样也是最快的。

另外,除了地址外,数值啥的都是 16 进制,可以直接转化为 10 进制进行解析。

logs

关于 logs 的解析请参考。

请我喝杯咖啡吧~