virtual void endOutput( const uint8_t *p, uint64_t value, const uint8_t *txHash, uint64_t outputIndex, const uint8_t *outputScript, uint64_t outputScriptSize ) { if (active) { numTxOutputs++; totalTxOutput += value; // Script uint8_t script[1 + 2*outputScriptSize]; toHex(script, outputScript, outputScriptSize); // Receiving address uint8_t address[40]; address[0] = 'X'; address[1] = 0; uint8_t addrType[3]; uint160_t pubKeyHash; int type = solveOutputScript(pubKeyHash.v, outputScript, outputScriptSize, addrType); if(likely(0<=type)) hash160ToAddr(address, pubKeyHash.v); // N.B. Input hash and index are NULL at this stage fprintf(outputFile, "%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",\"%s\",\"%s\",,\n", txID, outputIndex, value, script, address); } }
virtual void endOutput( const uint8_t *p, uint64_t value, const uint8_t *txHash, uint64_t outputIndex, const uint8_t *outputScript, uint64_t outputScriptSize ) { uint8_t address[40]; address[0] = 'X'; address[1] = 0; uint8_t addrType[3]; uint160_t pubKeyHash; int type = solveOutputScript( pubKeyHash.v, outputScript, outputScriptSize, addrType ); if (likely(0 <= type)) { hash160ToAddr( address, pubKeyHash.v, false, addrType[0] ); } if (blkID >= firstBlock) { fprintf( outputFile, "%" PRIu64 "|" "%s|" "%" PRIu64 "|" "%" PRIu64 "|" "%" PRIu32 "\n" , outputID, address, value, txID, (uint32_t)outputIndex ); } uint32_t oi = outputIndex; uint8_t *h = allocHash256(); memcpy(h, txHash, kSHA256ByteSize); uintptr_t ih = reinterpret_cast<uintptr_t>(h); uint32_t *h32 = reinterpret_cast<uint32_t *>(ih); h32[0] ^= oi; outputMap[h] = outputID++; }
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 void wrapup() { size_t size = boost::num_vertices(graph); info( "done, %.2f secs, found %" PRIu64 " address(es) \n", 1e-6*(usecs() - startTime), size ); info("Clustering ... "); startTime = usecs(); std::vector<uint64_t> cc(size); uint64_t nbCC = boost::connected_components(graph, &cc[0]); info( "done, %.2f secs, found %" PRIu64 " clusters.\n", 1e-6*(usecs() - startTime), nbCC ); auto e = rootHashes.end(); auto i = rootHashes.begin(); while(e!=i) { uint64_t count = 0; const uint8_t *keyHash = (i++)->v; uint8_t b58[128]; hash160ToAddr(b58, keyHash); info("Address cluster for address %s:", b58); auto j = addrMap.find(keyHash); if(unlikely(addrMap.end()==j)) { warning("specified key was never used to spend coins"); showFullAddr(keyHash); printf("\n"); count = 1; } else { uint64_t addrIndex = j->second; uint64_t homeComponentIndex = cc[addrIndex]; for(size_t k=0; likely(k<cc.size()); ++k) { uint64_t componentIndex = cc[k]; if(unlikely(homeComponentIndex==componentIndex)) { Addr *addr = allAddrs[k]; showFullAddr(addr->v); printf("\n"); ++count; } } } info("%" PRIu64 " addresse(s)\n", count); } }
static void showScriptInfo( const uint8_t *outputScript, uint64_t outputScriptSize ) { uint8_t type[128]; const char *typeName = "unknown"; uint8_t pubKeyHash[kSHA256ByteSize]; int r = solveOutputScript(pubKeyHash, outputScript, outputScriptSize, type); switch(r) { case 0: { typeName = "pays to hash160(pubKey)"; break; } case 1: { typeName = "pays to explicit uncompressed pubKey"; break; } case 2: { typeName = "pays to explicit compressed pubKey"; break; } case 3: { typeName = "pays to hash160(script)"; break; } case 4: { typeName = "pays to hash160(script)"; break; } case -2: { typeName = "broken script generated by p2pool - coins lost"; break; } case -1: { typeName = "couldn't parse script"; break; } } printf("\n"); printf(" script type = %s\n", typeName); if(0<=r) { uint8_t btcAddr[64]; hash160ToAddr(btcAddr, pubKeyHash); printf(" script pays to address %s\n", btcAddr); } }
virtual void endOutput( const uint8_t *p, uint64_t value, const uint8_t *txHash, uint64_t outputIndex, const uint8_t *outputScript, uint64_t outputScriptSize ) { uint8_t address[40]; address[0] = 'X'; address[1] = 0; uint8_t addrType[3]; uint160_t pubKeyHash; int type = solveOutputScript(pubKeyHash.v, outputScript, outputScriptSize, addrType); if(likely(0<=type)) hash160ToAddr(address, pubKeyHash.v); // id BIGINT PRIMARY KEY // dstAddress CHAR(36) // value BIGINT // txID BIGINT // offset INT fprintf( outputFile, "%" PRIu64 "\t" "%s\t" "%" PRIu64 "\t" "%" PRIu64 "\t" "%" PRIu32 "\n" , outputID, address, value, txID, (uint32_t)outputIndex ); uint32_t oi = outputIndex; uint8_t *h = allocHash256(); memcpy(h, txHash, kSHA256ByteSize); uintptr_t ih = reinterpret_cast<uintptr_t>(h); uint32_t *h32 = reinterpret_cast<uint32_t*>(ih); h32[0] ^= oi; outputMap[h] = outputID++; }
static bool testHash2Addr( const char *addr, const char *hexHash ) { auto ok = true; uint8_t buf[64]; uint8_t hash[kRIPEMD160ByteSize]; fromHex(hash, (const uint8_t*)hexHash, sizeof(hash), false); hash160ToAddr(buf, (uint8_t*)hash); TEST_CHECK( ok, 0==strcmp((char*)buf, addr), "encode fail\n" " for hash: %s\n" " expected: %s\n" " got : %s\n" "\n", hexHash, addr, (char*)(buf) ); return ok; }
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); }