Pages:
Author

Topic: [ANN] chainsnort (live transaction monitoring and fingerprinting tool) (Read 24569 times)

full member
Activity: 209
Merit: 148
Can someone build an update for this ?  Cool

Define update - do you mean adding new features, or updated binaries?
legendary
Activity: 1512
Merit: 1012
Can someone build an update for this ?  Cool
newbie
Activity: 24
Merit: 0
This tool is fantastic for my node. A great idea.
Thank you for release
full member
Activity: 124
Merit: 100

Very cool now we have a look and evaluate mainly under Linux
member
Activity: 96
Merit: 10
esotericnonsense
Hello,

I've been playing around recently with adding this functionality to my bitcoind front-end.

Those of you who aren't running full nodes will not find this useful. However, if you do have a full node, you can do all of this locally without external API requests. It may even be faster (I have not tested chainsnort, so I do not know.)

https://github.com/esotericnonsense/bitcoind-ticker

At the moment this is just a proof of concept and does the absolute bare minimum required. No highlighting or anything fancy, just spews out transactions to the terminal. The idea is there though.
member
Activity: 77
Merit: 10
Thanks a ton, Newar. God, this code is so much simpler than the Rust I'm doing my version in.
legendary
Activity: 1358
Merit: 1001
https://gliph.me/hUF
Does anyone have a copy of the code? I'm trying to build something similar.

I thought I did, but turns out I didn't  Undecided . All I can find for gistfile1.py (posted Jul 6, 2015): https://www.snip2code.com/Snippet/576729/chainsnort-0-484--latest_stable-

I gave it a quick go and after creating an empty file called prefixes.txt, it seems to work ok.

flatfly was last active on August 01, 2015, so until he comes back I put it on github as a backup. You can get it using:
Code:
wget https://raw.githubusercontent.com/Newar417/flatfly_archived_chainsnort/master/gistfile1.py

Code from snip2code:
Code:
import json, os, sys, datetime, time, urllib, websocket, operator, random, re
from colorama import Fore, Style, init   ; init()
  
t0 = time.time() ; Z = 0 ; nboutputs = 0 ; nbinputs = 0
VERBOSE = 1

print 'chainsnort v0.484: ' ,
os.system('title chainsnort_inspect [mainnet]')
matches = open('prefixes.txt').read().split()
matches2 = ['111111','XXXXXX']  

mini_easter_egg = ['** THANKS! **    (' +chr(3)+ ' _ ' +chr(3)+ ')        ','** PEACE! **     (^ _ ^)        ']


class Plex(object):
    def __init__(self, name):
        self.file = open(name, 'w')
        self.stdout = sys.stdout
        sys.stdout = self
    def __del__(self):
        sys.stdout = self.stdout
        self.file.close()
    def write(self, data):
    
        self.stdout.write(data)
        data=data.replace(chr(8),'')
        data=data.replace(chr(0x1B),'')
        data=re.sub('\[.*m','',data)
        # data=re.sub('\t ','X', data)

        self.file.write(data)


def main():
  global Z, btcseen
  btcseen = 0
  
  while (1):
    bigtag = '  '
    result = ws.recv()
    time.sleep(0.05)
    result = json.loads(result)
    if result['op'] == 'block' :
      print
      reward = result['x']['reward']/1e8  
      print datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-3] , bigtag + ' {:11.4f}'.format(reward) ,'B  [NEW BLOCK SOLVED] ' ,
      print Fore.CYAN+Style.BRIGHT + str(result['x']['height']) + Fore.RESET+Style.NORMAL
      print
      continue
   
    inputs = sum(p['prev_out']['value'] for p in result['x']['inputs']  )
    outputs = sum(p['value'] for p in result['x']['out']  )
    feepaid = (inputs-outputs)/1e8
    val = sum(p['value'] for p in result['x']['out'])/1e8
    btcseen = btcseen + val

    if val >= 50:
     if val >= 5000:
      print '\a' ,
     bigtag = Fore.GREEN+Style.BRIGHT + '>>' #  + chr(16)*2
     time.sleep(0.3)

    feetag = ''
    if feepaid < 0.0001 or feepaid >= 0.01:  
     feetag = Fore.YELLOW+Style.BRIGHT

    if VERBOSE == 0:
        max_addr = sorted(result['x']['out'], key=operator.itemgetter('value'), reverse=True)[0]['addr']
        for ku in result['x']['out']:
         if any(s in ku['addr'] for s in matches):
           max_addr =  Fore.MAGENTA+Style.BRIGHT + max_addr + Fore.RESET+Style.NORMAL
            
        print '\b'+ datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-3], bigtag + ' {:11.4f}'.format(val) ,'B '  + Fore.RESET+Style.NORMAL , max_addr , '\t' , feetag ,  '\b'*6 + '{:12.8f}'.format(feepaid) + Fore.RESET+Style.NORMAL
  
    if VERBOSE == 1:
       nboutputs = 0 ; nbinputs = 0
 
       for ki in result['x']['inputs']:
           print ' '.ljust(30) , 'i', ki['prev_out']['addr']
           nbinputs += 1
       for ku in result['x']['out']:
           print ' '.ljust(30) , 'o', ku['addr']
           nboutputs += 1

       txcat =  ''  
       if any(s['prev_out']['addr'] in ku['addr'] for s in result['x']['inputs']):    
           txcat = '[WEB_SPEND]'
       if nboutputs > 2:
    txcat = '[AUTOMATED_PAYMENT]'
  if (nboutputs > 20) & (nbinputs == 1):
      txcat = '[FAUCET_PAYMENT]'
      if val >= 0.2:
          txcat = '[MIXER]'
      if val >= 20:
          txcat = '[MININGPOOL_PAYMENT]'
       if (val >= 50) & (nbinputs == 1):
    txcat = '[COLDSTORAGE_MOVE]'
       if (val <= 0.0011) & (nbinputs == 1):
    txcat = '[MICROTRANSACTION]'  
       if (nboutputs == 1) & (nbinputs == 1):
    txcat = '[ADDRESS_SWEEP]'
       if (nboutputs == 1) & (nbinputs > 1):
    txcat = '[ADDRESS_CONSOLIDATION]'      
       if txcat == '':  
           txcat = '[NATIVE_SPEND]'
       for ku in result['x']['out']:
           if any(s in ku['addr'] for s in matches) | ('1Lucky' in result['x']['inputs'][0]) :    # to fix
               txcat +=    ' [ONCHAIN_GAMING]'           # or in inputs as well
               break
       for ku in result['x']['out']:
           if any(s in ku['addr'] for s in matches2):
               txcat = '[COIN_DESTRUCTION]'      # also add DONATION
               break
       for ku in result['x']['out']:
           if ku['value'] < 546:  
               txcat = '[ILLEGAL]'
               break              
       for ku in result['x']['out']:
           if ku['value'] == 7800:
               if (nboutputs == 3):  
                  txcat = '[XCP_OP]'
               # print '\a'
               break  

       for ku in result['x']['out']:
           if ku['addr'][0] == '3':  
               txcat = Fore.CYAN+Style.BRIGHT + '[MULTISIG]'
               break
                
       print 'Transaction:   ' + result['x']['hash']

       print '\b'+ datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-3], bigtag + ' {:11.4f}'.format(val) ,'B '  + Fore.RESET+Style.NORMAL , Fore.RESET+Style.BRIGHT + txcat.ljust(32) + Fore.RESET+Style.NORMAL , ' ', feetag , '{:12.8f}'.format(feepaid) + Fore.RESET+Style.NORMAL
 
    Z += 1 ; print
 
try:
  sys.tracebacklimit = 0
  domain='blockchain.info'
  stat = int(urllib.urlopen('https://'+domain+'/q/24hrtransactioncount').read().decode("utf8"))
  print Fore.CYAN+Style.BRIGHT + '\b' + str(stat)  + Fore.RESET+Style.NORMAL +  ' new transactions in the last 24 hours  -  ' + Fore.CYAN+Style.BRIGHT  + '%02.02f' % (stat/86400.0) + Fore.RESET+Style.NORMAL + ' tx/sec'
  # print '\nEstablishing TLS tunnel...',  
  print '\nCapturing transactions on mainnet...  (Fingerprinting enabled)\r',  
  ws = websocket.create_connection("wss://ws."+domain+"/inv")
  ws.send('{"op":"unconfirmed_sub"}')  ;
  ws.send('{"op":"blocks_sub"}')
  # print 'Done. Waiting for new transactions...\r',
  
  if '-o' in sys.argv:
       Plex('../../../Log/txtrace.log')      
  
  time.sleep(0.3)
  main()
      
except KeyboardInterrupt:
  t1 = time.time()
  print
  print 'Closing threads... Done.'
  print 'Captured',Z, 'events - Transaction density: %02.02f' % (Z/(t1 - t0)) , 'tx/sec - Coins moved:' + ' {:5.4f}'.format(btcseen)
  sys.exit()

member
Activity: 77
Merit: 10
Does anyone have a copy of the code? I'm trying to build something similar.
legendary
Activity: 2912
Merit: 1060
legendary
Activity: 2912
Merit: 1060
newbie
Activity: 8
Merit: 0
Sorry, that websocket link is broken. curl -o didn't work either anymore for me. Try:
Code:
git clone https://github.com/liris/websocket-client.git

cd websocket-client

python setup.py install

wget https://gist.github.com/flatfly/8253870/raw/9733e34e469e1bcd8d0ae13565ade4eaa0490618/gistfile1.py

python gistfile1.py



I get this :

 # python setup.py install
Traceback (most recent call last):
  File "setup.py", line 1, in
    from setuptools import setup
ImportError: No module named setuptools

OS : Debian GNU/Linux 7

Any idea please ?
legendary
Activity: 1358
Merit: 1001
https://gliph.me/hUF
Sorry, that websocket link is broken. curl -o didn't work either anymore for me. Try:
Code:
git clone https://github.com/liris/websocket-client.git

cd websocket-client

python setup.py install

wget https://gist.github.com/flatfly/8253870/raw/9733e34e469e1bcd8d0ae13565ade4eaa0490618/gistfile1.py

python gistfile1.py

legendary
Activity: 1358
Merit: 1001
https://gliph.me/hUF
it said: bash: 1/: No such file or directory

Code:
curl -o websocket.py https://raw.github.com/liris/websocket-client/master/websocket.py

curl -o chainsnort.py https://gist.github.com/flatfly/8253870/raw/9733e34e469e1bcd8d0ae13565ade4eaa0490618/gistfile1.py

python chainsnort.py
legendary
Activity: 2912
Merit: 1060
Can someone help me with a little tut for linux, im new with linux


Just copy and paste into a terminal:

1/ curl -o websocket.py https://raw.github.com/liris/websocket-client/master/websocket.py

2/ curl -o chainsnort.py https://gist.github.com/flatfly/8253870/raw/9733e34e469e1bcd8d0ae13565ade4eaa0490618/gistfile1.py

3/ python chainsnort.py
newbie
Activity: 4
Merit: 2
Blockchain.info uses a special system that doesn't involve Python (as far as we know), they're most likely using a modified node that notifies them of transactions.

The easy way

Just use Blockchain.info's transaction notification service. Their web sockets api lets anyone subscribe to any bitcoin address
The hard way

If you want to listen to all latest transactions, and not to addresses you own, you're going to need more in depth control. Otherwise use Bitcoind and its wallet notify parameter. Check out PyNode, a Bitcoin node implementation in Python.

Thanks
Lissa
http://driverrestore.com/
full member
Activity: 154
Merit: 100
Exchanges don't publish lists of addresses they hold, this would make them easily auditable.
You can verify whether the address belong to exchange or no by dint of big transactions with huge number of inputs. No software required.
legendary
Activity: 2912
Merit: 1060
Very useful code!

One question though. I wrote my own version which basically just takes in any unconfirmed transaction and write it to a file. And I also tried the json API provided by blockchain.info.
***
https://blockchain.info/unconfirmed-transactions?format=json
***
What surprises me is that websocket missed several transactions. Is there any way to make sure that the websocket API will return ALL unconfirmed transactions?

Balloon

I doubt it, it's not meant to be a reliable api, you'll have to roll your own node possibly with that bitpay software
newbie
Activity: 9
Merit: 0
Very useful code!

One question though. I wrote my own version which basically just takes in any unconfirmed transaction and write it to a file. And I also tried the json API provided by blockchain.info.
***
https://blockchain.info/unconfirmed-transactions?format=json
***
What surprises me is that websocket missed several transactions. Is there any way to make sure that the websocket API will return ALL unconfirmed transactions?

Balloon
legendary
Activity: 2618
Merit: 1007
Exchanges don't publish lists of addresses they hold, this would make them easily auditable.
legendary
Activity: 2912
Merit: 1060
I have a business idea for you. Traders would pay to see large transactions entering and leaving exchanges.
Pages:
Jump to: