Since there's currently a lot of fuzz about pirateat40's operations (is it a ponzi? is it legit? where does he get his coins from/back, if he really sells them OTC? how is GPUMax fitting in?), I think one of the best ways to analyze the situation is to get an address that surely belongs to him, hope for combined inputs if he sends something from that address, assume these belong to him as well (as he'd need to have private keys for that) and work our way from there until we have all linked addresses to a single bitcoin address.
Also something like this might also be useful for other purposes and I haven't found many projects concerning this (one would be toolongdidntread.com)...
After that, we can assume this as his wallet and check the balance, money flows etc. (which is currently a bit beyond what I did so far).
The first problem I ran into however is:
Is my code so far really correct? I don't want to make accusations or draw conclusions when it turns out that I included an MtGox address out of stupidity...
Anyways, here's the code to track any address (supplied in the "trackaddr" list) for multiple inputs. It will iterate over the whole blockchain multiple times until no more new inputs are found. Because of recent blockchain spam, I limited it currently to block 160000 (enough for the address I have so far) and there's probably a nicer way than running ~10 times over the whole chain. I have a fast CPU however, so it doesn't really bother me atm, the bigger concern is if it is really doing what it's supposed to do and has no chance of picking up and including some random other addresses.
Code (with Armory's donation address up to block 170000):
from armoryengine import *
BDM_LoadBlockchainFile()
topBlock = TheBDM.getTopBlockHeight()
trackaddr = ['1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX']
taintedblocks = []
addratstart = len(trackaddr)
addratend = 0
iterations = 0
transactioncount = 0
while addratstart != addratend:
transactioncount = 0
iterations += 1
addratstart = len(trackaddr)
for h in xrange(0, 170000): #topBlock+1):
if h%10000 == 0:
print '\tScanned %d blocks' % h
print 'Found %d addresses so far.' % len(trackaddr)
header = TheBDM.getHeaderByHeight(h)
txList = header.getTxRefPtrList()
for tx in txList:
foundaddr = False
for nin in range(tx.getNumTxIn()):
txin = tx.getTxInRef(nin)
try:
senderAddr20 = TheBDM.getSenderAddr20(txin)
address = hash160_to_addrStr(senderAddr20)
#print address
if address in trackaddr:
foundaddr = True
print "FOUND TRANSACTION! At block " + str (h)
except:
pass
if foundaddr is True:
for nin in range(tx.getNumTxIn()):
txin = tx.getTxInRef(nin)
try:
senderAddr20 = TheBDM.getSenderAddr20(txin)
address = hash160_to_addrStr(senderAddr20)
trackaddr.append(address)
except:
pass
trackaddr = list(set(trackaddr))
transactioncount += 1
taintedblocks.append(h)
taintedblocks = list(set(taintedblocks))
addratend = len(trackaddr)
print trackaddr
print taintedblocks
print "Went through the blockchain %d times!" % iterations
print "Found %d transactions" % transactioncount
print "Found %d blocks where these transactions were included" % len(taintedblocks)
print "Found %d addresses" % addratend
Oh, and I won't post any results (it's easy with armory to include all found addresses to a "wallet" for example and read the spendable balance of that at each block) publicly or in PMs until I have verified this code to be correct! Also pirate seems to be quite paranoid about posting bitcoin addresses belonging to him, so good luck with finding some (unless you're a customer at BTCS&T, then you can of course use your deposit address).
Edit:
I was using armory 0.76 rc1 - the current 0.81 version throws:
Traceback (most recent call last):
File "!findwallet.py", line 29, in <module>
for nin in range(tx.getNumTxIn()):
File "xxxxxxxxx\Armory_0_81\CppBlockUtils.py"
, line 813, in <lambda>
__getattr__ = lambda self, name: _swig_getattr(self, TxRef, name)
File "xxxxxxxxx\Armory_0_81\CppBlockUtils.py"
, line 51, in _swig_getattr
raise AttributeError(name)
AttributeError: getNumTxIn