-
Notifications
You must be signed in to change notification settings - Fork 0
/
ethersBot.js
97 lines (81 loc) · 3.09 KB
/
ethersBot.js
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
const ethers = require('ethers')
const fs = require('fs')
const abi = fs.readFileSync('./abi.json', {encoding: 'utf8'});
let config = fs.readFileSync('./config.json', {encoding: 'utf8'})
require('dotenv').config();
const main = async () => {
// PingPong Contract Address
const contractAddress= '0x7D3a625977bFD7445466439E60C495bdc2855367'
// Web3 Provider - Infura
const provider = new ethers.providers.WebSocketProvider(
`wss://kovan.infura.io/ws/v3/${process.env.KEY}`
)
// Defining signer using the private key
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
// Contract Instance
const contract = new ethers.Contract(contractAddress, abi, signer);
// filter for filtering out Ping event on contract
filter = {
address: contractAddress,
topics: [
ethers.utils.id("Ping()")
]
}
// array of events
let events = [];
// config containing startBlock and the last registered nonce of the sender
// nonce is saved in case bot crashes and need to check if before crashing the last tx sent was mined or not
config = JSON.parse(config)
// current BlockNumber
const currentBlock = await provider.getBlockNumber();
// After crash check
const checkNonce = async () => {
const txCount = await provider.getTransactionCount(signer.address)
// checking if the last tx before crash went through or not
if(txCount == config.nonce) {
// if last tx didn't go through then startBlock will be decreased by 1, to resend that tx.
config.startBlock -= 1;
config.nonce -= 1;
}
}
if(config.nonce != 0) {
await checkNonce();
} else {
// When bot starts at beginning
const txCount = await provider.getTransactionCount(signer.address);
config.nonce = txCount-1;
}
// fetching all events from startBlock to currentBlock
events = await contract.queryFilter("Ping", config.startBlock, currentBlock)
const firePong = async (event) => {
let blockNumber = await event.blockNumber;
config.startBlock = blockNumber+1;
config.nonce += 1;
// saving new config to file to stay updated in case of crash.
fs.writeFileSync('./config.json', JSON.stringify(config));
tx = await contract.connect(signer).pong(event.transactionHash, {
"gasPrice": 2500000000
})
await tx.wait();
}
// flag is set to have no clashing nonce
// while sending pong corresponding to old events(till startBlock), and new event occurs.
let flag = 0;
const forLoop = async () => {
for(i in events) {
await firePong(events[i])
}
flag = 1;
}
forLoop();
// handling new events triggers
contract.on(filter, async(log) => {
if(flag == 0) {
// if old events are being handled then new events are pushed to the events array to avoid clashing txs.
events.push(log)
} else {
await firePong(log)
}
})
}
main()