virtual void wrapup() { info("done\n"); info("sorting by balance ..."); CompareAddr compare; auto e = allAddrs.end(); auto s = allAddrs.begin(); std::sort(s, e, compare); info("done\n"); uint64_t nbRestricts = (uint64_t)restrictMap.size(); if(0==nbRestricts) info("dumping all balances ..."); else info("dumping balances for %" PRIu64 " addresses ...", nbRestricts); uint64_t i = 0; uint64_t nonZeroCnt = 0; while(likely(s<e)) { Addr *addr = *(s++); if(0!=nbRestricts) { auto r = restrictMap.find(addr->hash.v); if(restrictMap.end()==r) continue; } printf("%24.8f ", (1e-8)*addr->sum); showHex(addr->hash.v, kRIPEMD160ByteSize, false); if(0<addr->sum) ++nonZeroCnt; if(i<5000 || 0!=nbRestricts) { uint8_t buf[64]; hash160ToAddr(buf, addr->hash.v); printf(" %s", buf); } struct tm gmTime; time_t last = addr->lastTouched; gmtime_r(&last, &gmTime); char timeBuf[256]; asctime_r(&gmTime, timeBuf); size_t sz =strlen(timeBuf); if(0<sz) timeBuf[sz-1] = 0; printf(" %s\n", timeBuf); ++i; } info("done\n"); info("found %" PRIu64 " addresses with non zero balance", nonZeroCnt); info("found %" PRIu64 " addresses in total", (uint64_t)allAddrs.size()); info("shown:%" PRIu64 " addresses", (uint64_t)i); }
virtual int init( int argc, const char *argv[] ) { offset = 0; curBlock = 0; lastBlock = 0; firstBlock = 0; addrMap.setEmptyKey(emptyKey); addrMap.resize(15 * 1000 * 1000); allAddrs.reserve(15 * 1000 * 1000); optparse::Values &values = parser.parse_args(argc, argv); cutoffBlock = values.get("atBlock"); showAddr = values.get("withAddr"); detailed = values.get("detailed"); limit = values.get("limit"); auto args = parser.args(); for(size_t i=1; i<args.size(); ++i) { loadKeyList(restricts, args[i].c_str()); } if(0<=cutoffBlock) { info("only taking into account transactions before block %" PRIu64 "\n", cutoffBlock); } if(0!=restricts.size()) { info( "restricting output to %" PRIu64 " addresses ...\n", (uint64_t)restricts.size() ); auto e = restricts.end(); auto i = restricts.begin(); restrictMap.setEmptyKey(emptyKey); while(e!=i) { const uint160_t &h = *(i++); restrictMap[h.v] = 1; } } else { if(detailed) { warning("asking for --detailed for *all* addresses in the blockchain will be *very* slow"); warning("as a matter of fact, it likely won't ever finish unless you have *lots* of RAM"); } } info("analyzing blockchain ..."); return 0; }
virtual int init( int argc, char *argv[] ) { curBlock = 0; lastBlock = 0; firstBlock = 0; addrMap.setEmptyKey(emptyKey); addrMap.resize(15 * 1000 * 1000); allAddrs.reserve(15 * 1000 * 1000); option::Stats stats(usageDescriptor, argc, argv); option::Option *buffer = new option::Option[stats.buffer_max]; option::Option *options = new option::Option[stats.options_max]; option::Parser parse(usageDescriptor, argc, argv, options, buffer); if(parse.error()) exit(1); for(int i=0; i<parse.nonOptionsCount(); ++i) { loadKeyList(restricts, parse.nonOption(i)); } if(0!=restricts.size()) { info( "restricting output to %" PRIu64 " addresses ...\n", (uint64_t)restricts.size() ); auto e = restricts.end(); auto i = restricts.begin(); restrictMap.setEmptyKey(emptyKey); while(e!=i) { const uint160_t &h = *(i++); restrictMap[h.v] = 1; } } info("analyzing blockchain ..."); delete [] options; delete [] buffer; return 0; }
virtual void wrapup() { info("done\n"); info("sorting by balance ..."); CompareAddr compare; auto e = allAddrs.end(); auto s = allAddrs.begin(); std::sort(s, e, compare); info("done\n"); uint64_t nbRestricts = (uint64_t)restrictMap.size(); if(0==nbRestricts) info("dumping all balances ..."); else info("dumping balances for %" PRIu64 " addresses ...", nbRestricts); printf( "---------------------------------------------------------------------------------------------------------------------------------------------------------------------\n" " Balance Hash160 Base58 nbIn lastTimeIn nbOut lastTimeOut\n" "---------------------------------------------------------------------------------------------------------------------------------------------------------------------\n" ); int64_t i = 0; int64_t nonZeroCnt = 0; while(likely(s<e)) { if(0<=limit && limit<=i) break; Addr *addr = *(s++); if(0!=nbRestricts) { auto r = restrictMap.find(addr->hash.v); if(restrictMap.end()==r) continue; } printf("%24.8f ", (1e-6)*addr->sum); showHex(addr->hash.v, kRIPEMD160ByteSize, false); if(0<addr->sum) ++nonZeroCnt; if(i<showAddr || 0!=nbRestricts) { uint8_t buf[64]; hash160ToAddr(buf, addr->hash.v); printf(" %s", buf); } else { printf(" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); } char timeBuf[256]; gmTime(timeBuf, addr->lastIn); printf(" %6" PRIu64 " %s ", addr->nbIn, timeBuf); gmTime(timeBuf, addr->lastOut); printf(" %6" PRIu64 " %s\n", addr->nbOut, timeBuf); if(detailed) { auto e = addr->outputVec->end(); auto s = addr->outputVec->begin(); while(s!=e) { printf(" %24.8f ", 1e-6*s->value); gmTime(timeBuf, s->time); showHex(s->upTXHash); printf("%4" PRIu64 " %s", s->outputIndex, timeBuf); if(s->downTXHash) { printf(" -> %4" PRIu64 " ", s->inputIndex); showHex(s->upTXHash); } printf("\n"); ++s; } printf("\n"); } ++i; } info("done\n"); info("found %" PRIu64 " addresses with non zero balance", nonZeroCnt); info("found %" PRIu64 " addresses in total", (uint64_t)allAddrs.size()); info("shown:%" PRIu64 " addresses", (uint64_t)i); printf("\n"); exit(0); }
void move( const uint8_t *script, uint64_t scriptSize, const uint8_t *upTXHash, int64_t outputIndex, int64_t value, const uint8_t *downTXHash = 0, uint64_t inputIndex = -1 ) { uint8_t addrType[3]; uint160_t pubKeyHash; int type = solveOutputScript(pubKeyHash.v, script, scriptSize, addrType); if(unlikely(type<0)) return; if(0!=restrictMap.size()) { auto r = restrictMap.find(pubKeyHash.v); if(restrictMap.end()==r) { return; } } Addr *addr; auto i = addrMap.find(pubKeyHash.v); if(unlikely(addrMap.end()!=i)) { addr = i->second; } else { addr = allocAddr(); memcpy(addr->hash.v, pubKeyHash.v, kRIPEMD160ByteSize); addr->outputVec = 0; addr->nbOut = 0; addr->nbIn = 0; addr->sum = 0; if(detailed) { addr->outputVec = new OutputVec; } addrMap[addr->hash.v] = addr; allAddrs.push_back(addr); } if(0<value) { addr->lastIn = blockTime; ++(addr->nbIn); } else { addr->lastOut = blockTime; ++(addr->nbOut); } addr->sum += value; if(detailed) { struct Output output; output.value = value; output.time = blockTime; output.upTXHash = upTXHash; output.downTXHash = downTXHash; output.inputIndex = inputIndex; output.outputIndex = outputIndex; addr->outputVec->push_back(output); } }