|
const fs = require('fs'); |
|
const Web3 = require('web3'); |
|
const createCsvWriter = require('csv-writer').createObjectCsvWriter; |
|
|
|
var config = require('./config.json'); |
|
const web3 = new Web3(config['provider']); |
|
|
|
var tokenAddr = config['contractAddress']; |
|
var subAddr = tokenAddr.substr(0,4) + '...' + tokenAddr.substr(40,2); |
|
var fromBlock = config['fromBlock']; |
|
var toBlock = config['toBlock']; |
|
var tokenABI = config['abi']; |
|
|
|
var token = new web3.eth.Contract(tokenABI, tokenAddr); |
|
var addrs = []; |
|
|
|
const csvWriter = createCsvWriter({ |
|
path: 'holders_' + subAddr + '.csv', |
|
header: [ |
|
{id: 'addr', title: 'holder'}, |
|
{id: 'balance', title: 'balance'}, |
|
] |
|
}); |
|
|
|
const SplitGetEvents = async (start, end) => { |
|
var evs = [] |
|
try { |
|
evs = await token.getPastEvents('Transfer', {fromBlock:start, toBlock:end}); |
|
} catch (err) { |
|
if (err.message === 'Returned error: query returned more than 10000 results') { |
|
const middle = Math.round((start + end) / 2); |
|
console.log('Infura 10000 limit [' + start + '..' + end + '] ' + |
|
'-> [' + start + '..' + middle + '] ' + |
|
'and [' + (middle + 1) + '..' + end + ']'); |
|
var levs = await SplitGetEvents(start, middle); |
|
var revs = await SplitGetEvents(middle + 1, end); |
|
return levs.concat(revs); |
|
} |
|
} |
|
return evs; |
|
} |
|
|
|
const TokenHolders = async () => { |
|
if (toBlock == 'latest') { |
|
let number = await web3.eth.getBlockNumber() |
|
toBlock = number; |
|
console.log(toBlock); |
|
} |
|
|
|
console.log('get all token holders of ' + subAddr + ' from block ' + fromBlock + ' to ' + toBlock); |
|
var evs = await SplitGetEvents(fromBlock, toBlock); |
|
evs.forEach(e => { |
|
addrs.push(e.returnValues.to); |
|
}); |
|
addrs = Array.from(new Set(addrs)); |
|
return addrs; |
|
} |
|
|
|
TokenHolders().then(res => { |
|
fs.writeFile('holders_' + subAddr + '.txt', res.join('\n'), err => { |
|
if (err) { |
|
console.error(err) |
|
return |
|
} |
|
}) |
|
var records = []; |
|
var tasks = []; |
|
res.forEach(addr => { |
|
tasks.push(token.methods.balanceOf(addr).call().then(balance => { |
|
if (balance == 0) return; |
|
// console.log(addr, balance); |
|
records.push({'addr': addr, 'balance': balance}); |
|
})); |
|
}) |
|
Promise.all(tasks).then(() => { |
|
csvWriter.writeRecords(records).then(() => console.log('The CSV file was written successfully')); |
|
}); |
|
}); |