-
Notifications
You must be signed in to change notification settings - Fork 6
/
balances.js
105 lines (91 loc) · 3.2 KB
/
balances.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
/// balances.js -- RHOC balance reporting
// Copyright (C) 2018 dc <[email protected]>
// Copyright (C) 2019 Tomáš Virtus <[email protected]>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Apache License as published by the Apache
// Software Foundation, either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Apache License, Version 2 for more details.
//
// You should have received a copy of the Apache License, Version 2
// along with this program. If not, see <https://www.apache.org/licenses/>.
const Web3 = require('web3');
const deployAddr = '0x168296bb09e24a88805cb9c33356536b980d3fc5'
const deployBlock = 3383352
const tokenMintAddr = '0xe17C20292b2F1b0Ff887Dc32A73C259Fae25f03B'
const tokenSupply = 100000000000000000
const apiUrl = process.env.ETH_API_URL || process.env.ETH_WS || 'http://localhost:8545'
const toBlock = process.env.BLOCK || 'latest';
const dumpXfers = !!process.env.DUMP_XFERS
const chunkSize = process.env.CHUNK_SIZE || 1000000
const web3 = new Web3(apiUrl)
const rhoc = new web3.eth.Contract(require('./abi.json'), deployAddr);
async function* getTransferEvents(_toBlock) {
async function* getTransferEventsInRange(fromBlock, toBlock) {
for (ev of await rhoc.getPastEvents('Transfer', { fromBlock, toBlock } )) {
if (ev.blockNumber === null) {
console.warning('Got pending transfer event, skipping...')
continue
}
if (ev.removed) {
throw 'Got unexpected removed transfer event: ' + JSON.stringify(ev)
}
yield ev
}
}
let count = _toBlock - deployBlock + 1
let iters = Math.floor(count / chunkSize)
for (let i = 0; i < iters; i++) {
let fromBlock = deployBlock + i * chunkSize
let toBlock = deployBlock + (i + 1) * chunkSize - 1
yield* getTransferEventsInRange(fromBlock, toBlock)
}
let fromBlock = _toBlock - count % chunkSize + 1
if (fromBlock <= _toBlock)
yield* getTransferEventsInRange(fromBlock, _toBlock)
}
async function* getNetBalances(xferEventsIter) {
let balances = new Map()
balances[tokenMintAddr] = BigInt(tokenSupply)
for await (ev of xferEventsIter) {
let xfer = ev.returnValues
if (xfer.from === xfer.to)
continue
let amount = BigInt(xfer.value)
let fromBal = balances[xfer.from] || 0n // BigInt(0)
let toBal = balances[xfer.to] || 0n
balances[xfer.from] = fromBal - amount
balances[xfer.to] = toBal + amount
}
for ([addr, bal] of Object.entries(balances)) {
if (bal > 0) {
let c = await web3.eth.getCode(addr).then(code => code == '0x' ? 0 : 1)
yield [addr, bal, c]
}
}
}
(async () => {
let exitCode = 0
try {
let xferEventsIter = getTransferEvents(toBlock)
if (dumpXfers) {
for await (xferEvent of xferEventsIter) {
console.log(JSON.stringify(xferEvent))
}
} else {
for await ([addr, bal, c] of getNetBalances(xferEventsIter)) {
process.stdout.write(addr + ',' + bal + ',' + c + '\n')
}
}
} catch (e) {
console.error(e)
exitCode = 1
} finally {
process.exit(exitCode)
}
})();