-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfetcher.js
123 lines (100 loc) · 3.38 KB
/
fetcher.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
const https = require('https');
const fs = require('fs').promises;
const path = require('path');
function httpsRequest(url, options, body) {
return new Promise((resolve, reject) => {
const req = https.request(url, options, (res) => {
let data = '';
res.on('data', (chunk) => data += chunk);
res.on('end', () => resolve(JSON.parse(data)));
});
req.on('error', reject);
if (body) req.write(body);
req.end();
});
}
async function getEndpoint(apiKey) {
const options = {
headers: { 'x-api-key': apiKey }
};
const response = await httpsRequest(`https://api.quicknode.com/v0/endpoints`, options);
return response.data.find(e => e.chain === 'ethereum' && e.network === 'mainnet');
}
async function fetchBlockData(rpcUrl, blockNumber) {
const options = {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
};
const blockBody = JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'eth_getBlockByNumber',
params: ['0x' + blockNumber.toString(16), true]
});
const blockData = await httpsRequest(rpcUrl, options, blockBody);
const receiptPromises = blockData.result.transactions.map(tx => {
const receiptBody = JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'eth_getTransactionReceipt',
params: [tx.hash]
});
return httpsRequest(rpcUrl, options, receiptBody);
});
const receipts = await Promise.all(receiptPromises);
const logsBody = JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'eth_getLogs',
params: [{ fromBlock: '0x' + blockNumber.toString(16), toBlock: '0x' + blockNumber.toString(16) }]
});
const logs = await httpsRequest(rpcUrl, options, logsBody);
const debugTraceBody = JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'debug_traceBlockByNumber',
params: ['0x' + blockNumber.toString(16), { tracer: 'callTracer' }]
});
const debugTrace = await httpsRequest(rpcUrl, options, debugTraceBody);
const traceBlockBody = JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'trace_block',
params: ['0x' + blockNumber.toString(16)]
});
const traceBlock = await httpsRequest(rpcUrl, options, traceBlockBody);
return {
block: blockData.result,
transactions: blockData.result.transactions,
receipts: receipts.map(r => r.result),
logs: logs.result,
debugTrace: debugTrace.result,
traceBlock: traceBlock.result
};
}
async function saveBlockData(blockNumber, data) {
const outputDir = 'quicknode_data';
await fs.mkdir(outputDir, { recursive: true });
const fileName = path.join(outputDir, `block_${blockNumber}.json`);
await fs.writeFile(fileName, JSON.stringify(data, null, 2));
console.log(`Data for block ${blockNumber} saved to ${fileName}`);
}
async function main() {
//https://dashboard.quicknode.com/api-keys
const apiKey = 'YOUR_QUICKNODE_API_KEY';
try {
const endpoint = await getEndpoint(apiKey);
if (!endpoint) {
throw new Error('No suitable endpoint found');
}
for (let blockNumber = 1000000; blockNumber <= 1000010; blockNumber++) {
console.log(`Fetching data for block ${blockNumber}`);
const blockData = await fetchBlockData(endpoint.http_url, blockNumber);
await saveBlockData(blockNumber, blockData);
}
console.log('All block data has been fetched and saved.');
} catch (error) {
console.error('Error:', error);
}
}
main();