GithubHelp home page GithubHelp logo

bitcoin-sniffer's People

Contributors

sebicas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bitcoin-sniffer's Issues

How to tell if the block will be part of the main chain?

After finding that the block comes with no 'block height' I found this question: http://bitcoin.stackexchange.com/questions/24309/is-block-height-always-sequential

Block height is by definition sequential in the sense that adjacent blocks will always have heights that differ by 1. But there is a chicken-and-egg problem: in order to compute the height, you have to have access to all the blocks in between the genesis block and the current one. (The height is not recorded in the block itself.)
There's also the issue that multiple blocks can have the same height, if they are on different branches of the chain. So just because you have one block at every height, doesn't mean you have all the blocks on the main chain; some of them might be on orphan branches.

what is block.is_valid? and how can i tell if the block is official and will not be replaced by a 'better' block?

Where is the From Address?

In a valid transaction I can see the Address the Bitcoin is send but I cannot see from where the Bitcoin is coming?
Kindly help.

How I can find each tx.hash in the block?

I am tracking a tx as it gets broadcasted in new_transaction_event then I'm trying to find the tx.hash to see that it has been included in the block

def new_block_event(block):
    print block
    #for tx in block.vtx:
        #print dir(tx)
    #   print "\n\n"
    #   for out in tx.vout:
    #       print out.address
    #       print "\n"
    #       print out.amount
    #       print "\n"
    #       for ba in out.build_address:
    #           print dir(ba)
    #       print "\n"
    #       for de in out.deserialize:
    #           print dir(de)
    #       print out.deserialize
    #       print "\n"
    #       print out.nValue
    #       for se in out.serialize:
    #           print dir(se)
            #print "\n"
            #print out.scriptPubKey
            #print "\n"
            #print out.serialize

If I print out the block the only hashes I see looks like:

CTxIn(prevout=COutPoint(hash

the block is so messy I can't make out the structure!

in the block there should be a list of included txs (i thought this might me vout) and each tx should have a hash to it can be matched with tx seen in new_transaction_event

please can you explain how I can find each tx.hash in the block?

Connecting to Bitcoin Node

[root@localhost bitcoin-sniffer]# ./sniffer.py
running on predefined node ip
Bitcoin Network Sniffer v0.0.2

Connecting to Bitcoin Node IP # 173.242.112.53:8333
error: uncaptured python exception, closing channel <main.NodeConn 173.242.112.53:8333 at 0x1fce8c0> (<class 'socket.error'>:[Errno 110] Connection timed out [/usr/lib64/python2.7/asyncore.py|read|83] [/usr/lib64/python2.7/asyncore.py|handle_read_event|446] [/usr/lib64/python2.7/asyncore.py|handle_connect_event|454])
Closing Conection ... bye :)

running on my node ip
[root@localhost bitcoin-sniffer]# ./sniffer.py

Bitcoin Network Sniffer v0.0.2

Connecting to Bitcoin Node IP # 198.204.2.34:8333
Connected & Sniffing :)

Closing Conection ... bye :)
Closing Conection ... bye :)

Do I need a local node? HowTo remote node?

Hi I wonder if I can have a remote node and how can I get the connection working. Thinking that I will probably be on a small VPS with limited storage, I wonder how can I code to a remote blockchain at least to find events and transactions.

This used to work!

Is this sniffer no longer compatible with bitcoin?

the socket closes here:

if len(t) == 0:
    print "here_" + t + "_"
    self.handle_close()

Bitcoin Network Sniffer v0.0.2

Connecting to Bitcoin Node IP # 77.148.254.178:8333
Connected & Sniffing :)

Closing Conection ... bye :)
here__
Closing Conection ... bye :)

Unknown command: 'reject' '\x07version\x11 Version must be 31800 or greater

I had to change line 27 to

MY_VERSION = 31800

as all nodes on https://blockchain.info/connected-nodes stopped working

Error:

Send msg_version(nVersion=312 nServices=1 nTime=Mon Sep 26 16:46:46 2016 addrTo=CAddress(nServices=1 ip=76.102.46.197 port=8333) addrFrom=CAddress(nServices=1 ip=0.0.0.0 port=0) nNonce=0x39511B30ECACB922 strSubVer=.4 nStartingHeight=-1)"}
{"sniffer":"76.102.46.197:8333"}
{"sniffer":"Connected"}
{"sniffer":"Unknown command: 'reject' '\x07version\x11 Version must be 31800 or greater'"}
{"sniffer":"Recv msg_ping()"}
{"sniffer":"Unknown command: 'getheaders' '\xd1\x00\x00\x00\x1e\x06l$!\x1a)\xbf\xd0<\x93f$\xbc\xeb6\xd7\x0b\xbe\x8a\xab\xcd\x92\xcd\x02\x00\x00\x00\x00\x00\x00\x00\x00;P\xcca\x9c\x8e\xa2\x0eD\x87,q,\xb2\xe2\xbbH$\xb0\xfe\xad\x90\n\x04\x00\x00\x00\x00\x00\x00\x00\x00]\xdf\x93NN[\xed\xfb\x13\xf2\xf1\xd2\x84|\x02\xeb\x99\xdd\xd6\xa7\niZ\x04\x00\x00\x00\x00\x00\x00\x00\x00\xfc)\xcc\x8c\xbf\xb1\x14\x10\x93\x1d\x82\xd4\xaf<I\xbd\xebJ r\xea~\xb8\x02\x00\x00\x00\x00\x00\x00\x00\x00\x08\x18\x184\xff\xff]\xecn\xd9\x0c\xbe\x8d%\xc2{{\'\xe2i;\x934\x03\x00\x00\x00\x00\x00\x00\x00\x00\xb5\x83i\xf56\xd9\x90\xb1;\x8d\x06A\xe3N\xd3\xb0\x81t\x8e\r\x03\x97-\x02\x00\x00\x00\x00\x00\x00\x00\x00\xeb\xca\xe3cM\xffr\xee6\xf4\xac\x1b\xe9\xcf5\xe9\xd6\x16"\xb9\x82\x9f}\x04\x00\x00\x00\x00\x00\x00\x00\x00]R\\t|O\xcf\xf9<m\x16\x93\x82\x9a\x07\xe9b\x12\x9e\xfeB\x8a\x12\x03\x00\x00\x00\x00\x00\x00\x00\x00\x9dmn\x82\xcf\x84\x04Tj\xa9\xfa\xc0\xac,\x004+b\xc0\x8fD\x822\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd53\xec3)6l\x10\x98\xeds\x04\xe7\x84\x04o\xe0YU\xe7\x7f\x06N\x03\x00\x00\x00\x00\x00\x00\x00\x00n\x8d\xf9<\x11\r\xb2\'\x069\x04\xdc\xa6\xa0{_\xc2\xe3\xba\xa4\xd3\x14\xf0\x03\x00\x00\x00\x00\x00\x00\x00\x00,\xbfe\xf5\xd4\xb1\xb3D\xc9\x1c\'\x0e\xe7sb\xe9\xac\xd0Ih\xc8\xf11\x03\x00\x00\x00\x00\x00\x00\x00\x00\xa8\xc7\xe7\x9e\x99\xcc\x81f3r \x9a\xd9\x88\xda\xccl\xfd\x95\xc3\x11\xe5P\x04\x00\x00\x00\x00\x00\x00\x00\x00\xfb/\xf1\xfcS\xfc8M\t\x0bP\x91V\xdf_\x0f \x97\xf4\xd0\xc2\x18\x18\x02\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xd3\xae\xe6[\xa6-\xc0u\xe5\x8a\xef\xa9h\xbf\xceS\xb0\xbd\xcf\xa6\xb8\x96\x02\x00\x00\x00\x00\x00\x00\x00\x00-\x8a/\xd3\x87\n\xb4\xf2a\xa3[el\x90\x94\xf2b\xc5\xc8\xbe\x06\xcex\x03\x00\x00\x00\x00\x00\x00\x00\x00\xcfg\xbf\xdc\x05\xce\xd2\xaaT\xc1\x93Y\xe2\xca\r^W\x1a\x8d\xb8\xafc\xca\x02\x00\x00\x00\x00\x00\x00\x00\x00_1\x0e\xedP\x98\xd5%@FJ\x16\xb2S\xb3mA\xd6\xf8\xc4\xb4\x12\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\ts\xfd`\xcc)\xeb3\xe3\x11\x9f(\x06\xa6\xd3c\x1d>I\xb5\xf9WA\x03\x00\x00\x00\x00\x00\x00\x00\x00Q\x93Q\x0b\xa1u>\x0c\xfa\x9a\xe6\xa6\xe5\xac\x7f0\x08\xee\xa5\xc1\x9bQZ\x02\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xfcYXw\xaf\x87\x91H\x9f\xc4S4U\t\xa8=bj\xcf\xad\xbc\x84\x01\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xf5\x92\x11\x869dl0\xbbD\xf4\x03_\xa2yt\x18\xa4|\x827\x92\x02\x00\x00\x00\x00\x00\x00\x00\x00M\xe9\xd9Y\x00f\xacb\xc66\xd6=\xa1\\oMRT\xa7\xfa\xe7\xa5\xac\x00\x00\x00\x00\x00\x00\x00\x00\x00<>\xce\xd9\xfdw\xe9q\x89)\xbdT\x9b\x1ex\x80\xf3\xe9\x8ew\xfd&\x06\x02\x00\x00\x00\x00\x00\x00\x00\x00\xe4\xab\nXT\x8a\xado\xe2\x85\x049\xa2\x93Qr\tUv\xd6&\xdd\xbc\x01\x00\x00\x00\x00\x00\x00\x00\x00p\x94[&\xa1\x08Dr=\xde\xab[\xfc\xd5\x01\xd1\x80m\xa0@\xe7\xea>\x06\x00\x00\x00\x00\x00\x00\x00\x00\xab$_XSn9\xb4"+\x87\xe5g\xbb\xd2\x9f\x85x\xe3\xa1\xc8I\xc1\x0f\x00\x00\x00\x00\x00\x00\x00\x00\xc7\x07r\x1c\x82\xfe\xe3\t&>\x07\x83!\xe8\x9fJ\x84\xbd+\xd3\x8e\x1b!f\x00\x00\x00\x00\x00\x00\x00\x00\x12U\x95\xca\xb9\xdb\xdb\xff\x85\x05DSq{\xcd\x11J\xc8\xa5\xc7&>\x9d5\x19\x02\x00\x00\x00\x00\x00\x00o\xe2\x8c\n\xb6\xf1\xb3r\xc1\xa6\xa2F\xaec\xf7O\x93\x1e\x83e\xe1Z\x08\x9ch\xd6\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'"}
{"sniffer":"Closing"}
{"sniffer":"Closing"}

Fixed it

How to get transaction ?

How can we sniff the transaction based on To and from address format? I am trying to build my own datastore to store all the transaction.

Thanks for the awesome work. You have my star.

Testnet mode (almost)

Full code is at the bottom of this post

I've never done python before (I think I've done a pretty good job at not breaking it 👍 )

I changed

settings = {
    "debug": True,
    "network":"testnet"
}

nw = {
    "testnet":{"host":"188.226.202.220","port":18333,"ADDRESSVERSION":"\x6F","MSGHEADER":"\x0b\x11\x09\x07"},
    "mainnet":{"host":"76.102.46.197","port": 8333,"ADDRESSVERSION":"\x00","MSGHEADER":"\xf9\xbe\xb4\xd9"}
}

settings['host'] = nw[settings['network']]['host']
settings['port'] = nw[settings['network']]['port']
settings['ADDRESSVERSION'] = nw[settings['network']]['ADDRESSVERSION']
settings['MSGHEADER'] = nw[settings['network']]['MSGHEADER']

Then I:

  • found all (5) instances of "\x00" and replace them with settings['ADDRESSVERSION']
  • found all (2) instances of "\xf9\xbe\xb4\xd9" and replaced them with settings['MSGHEADER']
  • put a print 'function_name' inside every def so I can see (where) if it crashes/hangs

Next I tested in mainnet mode to see that it still works (it does) and to copy and paste the print log here.
Then I tested testnet mode; the print log shows that it connects but it looks like It doesn't get a message reply:

################################# testnet
NodeConn.__init__
msg_version.__init__
CAddress.__init__
CAddress.__init__
NodeConn.send_message
msg_version.__repr__
CAddress.__repr__
CAddress.__repr__
{"sniffer":"Send msg_version(nVersion=31800 nServices=1 nTime=Mon Sep 26 19:05:09 2016 addrTo=CAddress(nServices=1 ip=188.226.202.220 port=18333) addrFrom=CAddress(nServices=1 ip=0.0.0.0 port=0) nNonce=0x2EB0ECC69A7A23B5 strSubVer=.4 nStartingHeight=-1)"}
msg_version.serialize
CAddress.serialize
CAddress.serialize
ser_string
sha256
sha256
{"sniffer":"188.226.202.220:18333"}
NodeConn.readable
NodeConn.writable
NodeConn.handle_connect
{"sniffer":"Connected"}
NodeConn.readable
NodeConn.writable

Whereas in mainnet mode I recorded it up to the first tx message received:

################################# mainnet
NodeConn.__init__
msg_version.__init__
CAddress.__init__
CAddress.__init__
NodeConn.send_message
msg_version.__repr__
CAddress.__repr__
CAddress.__repr__
{"sniffer":"Send msg_version(nVersion=31800 nServices=1 nTime=Mon Sep 26 19:03:48 2016 addrTo=CAddress(nServices=1 ip=76.102.46.197 port=8333) addrFrom=CAddress(nServices=1 ip=0.0.0.0 port=0) nNonce=0xECDDD8A9AC0178E8 strSubVer=.4 nStartingHeight=-1)"}
msg_version.serialize
CAddress.serialize
CAddress.serialize
ser_string
sha256
sha256
{"sniffer":"76.102.46.197:8333"}
NodeConn.readable
NodeConn.writable
NodeConn.handle_connect
{"sniffer":"Connected"}
NodeConn.readable
NodeConn.writable
NodeConn.handle_read
NodeConn.got_data
sha256
sha256
msg_version.__init__
CAddress.__init__
CAddress.__init__
msg_version.deserialize
CAddress.__init__
CAddress.deserialize
CAddress.__init__
CAddress.deserialize
deser_string
NodeConn.got_message
msg_version.__repr__
CAddress.__repr__
CAddress.__repr__
{"sniffer":"Recv msg_version(nVersion=70002 nServices=1 nTime=Mon Sep 26 19:04:08 2016 addrTo=CAddress(nServices=1 ip=51.255.34.172 port=41896) addrFrom=CAddress(nServices=1 ip=76.100.12.4 port=8333) nNonce=0xFADF61FA0937F498 strSubVer=/Classic:0.11.2/ nStartingHeight=431641)"}
msg_verack.__init__
NodeConn.send_message
msg_verack.__repr__
{"sniffer":"Send msg_verack()"}
msg_verack.serialize
sha256
sha256
NodeConn.readable
NodeConn.writable
NodeConn.handle_read
NodeConn.got_data
sha256
sha256
msg_verack.__init__
msg_verack.deserialize
NodeConn.got_message
msg_verack.__repr__
{"sniffer":"Recv msg_verack()"}
sha256
sha256
NodeConn.got_message
{"sniffer":"Recv msg_ping()"}
sha256
sha256
{"sniffer":"Unknown command: 'getheaders' '8|\x00\x00\x1e\xa9\xd12\xa6\xc1\x98\x90\xf4ic>\xd7([\x16\xc8\xb5\xd7\xeb\xf0\xa45\xcc\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5=\xe0\xa8\xb5}\x83]\n\xd8\x85\xb0p\xef_v\x08\xed.o:\xb6\xce\x02\x00\x00\x00\x00\x00\x00\x00\x00\xbc>\xd3\x88\xe3\xc3~\xdbB\x96\xe1\xd4<Ca0\xcf9\x9a\x1cD\x8a\x9c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x1c\r~\xec\xd7\xe8z\xc1\xbc\x0e\xdd\xdd\x0b\xdc\x18\xe5\xf1\xad\x93\x83\x9c\x917\x02\x00\x00\x00\x00\x00\x00\x00\x00\xc8\xd5O\x8f\xd0\x19\x8e\xdf\xfc\xa7\xc2\x93h\xc2xn\x11rGssQ\x9e\x02\x00\x00\x00\x00\x00\x00\x00\x00\xae\xab\xc2\xae8(\xcf\xab=\x9c\x83\x84\xd0\x19\x8a\x0b-\x9do\x0c\x08\xaag\x03\x00\x00\x00\x00\x00\x00\x00\x00}\xad\xbaj)"7KV)\x89~L>\xbf_\x1e*\xe5\xa2\xa4*\xce\x00\x00\x00\x00\x00\x00\x00\x00\x00r\xe3\x1c\x96\xeb~j\xce\xef\xc8$\x14=\x07)\xcb\x92\xf6\x82\xeeC\x95\x8e\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8+I\r]\x11{\x99\x17\x9c\xa8\xf3\xcd\xa5+-\xe0\xc3-\x91}\xb3\x9d\x03\x00\x00\x00\x00\x00\x00\x00\x00\x8b\x19o\x85\xb1\x8cv\x1e\x8b\xe8\xb1\x1c=\xa3\x9e\xb0<\xd0\x9c\xc7\xf0B\xd6\x02\x00\x00\x00\x00\x00\x00\x00\x00`\xcdOcz\xf9\xbd>i8m\xf3\xdbE\xe7}\xed\x98\xd5Z\x92\xae\xbd\x01\x00\x00\x00\x00\x00\x00\x00\x004>\xa1`\x02\xe7\xe8\xcbN/\x8ew \x80y\x1a\x95>sY\xf1KP\x02\x00\x00\x00\x00\x00\x00\x00\x00;P\xcca\x9c\x8e\xa2\x0eD\x87,q,\xb2\xe2\xbbH$\xb0\xfe\xad\x90\n\x04\x00\x00\x00\x00\x00\x00\x00\x00\xb5\x83i\xf56\xd9\x90\xb1;\x8d\x06A\xe3N\xd3\xb0\x81t\x8e\r\x03\x97-\x02\x00\x00\x00\x00\x00\x00\x00\x00\xa8\xc7\xe7\x9e\x99\xcc\x81f3r \x9a\xd9\x88\xda\xccl\xfd\x95\xc3\x11\xe5P\x04\x00\x00\x00\x00\x00\x00\x00\x00\xc1!.1\x05\xe9\xc5-\xfd\xe4;\x17<\xdc0\x1a\x85\xb1\xb1\x12\xdc\x81\x00\x04\x00\x00\x00\x00\x00\x00\x00\x005\xb1M\xafX\xc5W\x0b~(\x8f\x97\x97\xfd\x0e\xdb\xb1\xdef\xec\x92P\\\x04\x00\x00\x00\x00\x00\x00\x00\x00Ri\xf6X\x91\xbfX&\x7f\xc2p$\xc4\rv\xa1\x83\xcf\xdd\xeb\x8c\xca\x18\x04\x00\x00\x00\x00\x00\x00\x00\x00]\xebDXv\x1b\r\xdf>\xc6t\x02\xf0\xcfw\xd3\x8f\xbd\xc9V\xfe\x98o\x04\x00\x00\x00\x00\x00\x00\x00\x00M\x014\x99\xf3\x94\xed\x84\x85Xmv\x07\r\x92\rDao\x8b,\xf5\xa9\x00\x00\x00\x00\x00\x00\x00\x00\x007\xda\xa8\x06\t\xfb\xdc\xcez\xebQ\xd5\x16\xd5`h,\xb9_#\x97\xbfr\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\xdc\x83\x1e\x93\x13<\x00\xc4\x1cX\xc0\x07\xf7\xb8\xca\xb3\xce\xd6\xb6e\xac\x94\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97if\xad\xc4\x9d\xf4g\xa7\nO\xad\xff2\xdbn/\xd9\x81\xa1\x8dx\xfd\x02\x00\x00\x00\x00\x00\x00\x00\x00\xde.\x9d\xd5\xe9\xdd\r\xfd\n\x08-l\xdfa\xc6\xb5\x8e,\x05\x98\x80\x96\x8a\x02\x00\x00\x00\x00\x00\x00\x00\x00\xf3\xac\tK\xbd\xd8\x98\xda\xa52?\xbb\xf6\x8b\x8c\x9d\xf4c\x83\'7\xc2\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00<\xc2\x9e\xdf\xb0\xd4\x13c\xe5=-\x81\xae\xec\x8cz*\xbd\xbd\xba\xd8\xf3\xf4\x00\x00\x00\x00\x00\x00\x00\x00\x00\xefh\x1d)F_\xdb\x02\xda\x0eF]\xa2\n\x8c\x86M\nO\xafk\x0c2\x11\x00\x00\x00\x00\x00\x00\x00\x00\x80\rk\xd6\x15\x06\x9d\xbb\x9et\xba\x81\xbcV\xdb\xb0\x84<j\xaa\xa0\xf8\x15\x13\x00\x00\x00\x00\x00\x00\x00\x00xo-h\x1eck\xb2e1\xc2\x8b\xe4\xb9\xba\x05\xf9\x1d\xf9?\x13\x87\r\x82\t\x01\x00\x00\x00\x00\x00\x00o\xe2\x8c\n\xb6\xf1\xb3r\xc1\xa6\xa2F\xaec\xf7O\x93\x1e\x83e\xe1Z\x08\x9ch\xd6\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'"}
NodeConn.readable
NodeConn.writable
NodeConn.handle_read
NodeConn.got_data
sha256
sha256
msg_inv.__init__
msg_inv.deserialize
deser_vector
CInv.__init__
CInv.deserialize
deser_uint256
NodeConn.got_message
msg_inv.__repr__
CInv.__repr__
{"sniffer":"Recv msg_inv(inv=[CInv(type=TX hash=38ed9b6c7230369b5791c5043ea16dc8a00dacc25e62e415b602bbd83dfc25d1)])"}

It might be something wrong with the first message we send! (Send msg_version?)

Full code:

#!/usr/bin/python
#
# sniffer.py - Bitcoin P2P Network Sniffer
# https://github.com/sebicas/bitcoin-sniffer by @sebicas
#
# This is a Fork of pynode mininode from jgarzik ( https://github.com/jgarzik/pynode )
# But since his version is a little know branch with in pynode I dedided to keep my
# Fork but contribute my changes to his repository.
#
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

import struct
import socket
import asyncore
import binascii
import time
import sys
import re
import random
import cStringIO
import hashlib
import json

SNIFFER_VERSION = "0.0.2"

MY_VERSION = 31800
MY_SUBVERSION = ".4"



# Default Settings if no configuration file is given

settings = {
    "debug": True,
    "network":"testnet"
}

nw = {
    "testnet":{"host":"188.226.202.220","port":18333,"rpc":18332,"ADDRESSVERSION":"\x6F","MSGHEADER":"\x0b\x11\x09\x07"},
    "mainnet":{"host":"76.102.46.197","port": 8333,"rpc": 8332,"ADDRESSVERSION":"\x00","MSGHEADER":"\xf9\xbe\xb4\xd9"}
}

settings['host'] = nw[settings['network']]['host']
settings['port'] = nw[settings['network']]['port']
settings['rpc'] = nw[settings['network']]['rpc']
settings['ADDRESSVERSION'] = nw[settings['network']]['ADDRESSVERSION']
settings['MSGHEADER'] = nw[settings['network']]['MSGHEADER']



def new_block_event(block):
    if block.is_valid():
        json = "'{"+'"type":"block","hash":"'+block.hash+'","transaction_hashes":['
        for tx in block.vtx:
            json+='"'+tx.hash+'",'
        json=json[:-1]+"]}'"
        print json


def new_transaction_event(tx):
    json = "'{"+'"type":"tx",'
    if tx.is_valid():
        json+='"hash":"'+tx.hash+'",'
        json+='"outputs":['
        for txout in tx.vout:
            json+='{"addresses":["'+txout.address+'"],"amount":'+str(txout.amount)+'},'
        json=json[:-1]+"]}'"
        print json

def sha256(s):
    print 'sha256'
    return hashlib.new('sha256', s).digest()

def hash256(s):
    print 'hash256'
    return sha256(sha256(s))

def b58encode(v):
    print 'b58encode'
    b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
    long_value = 0L
    for (i, c) in enumerate(v[::-1]):
        long_value += (256**i) * ord(c)
    result = ''
    while long_value >= 58:
        div, mod = divmod(long_value, 58)
        result = b58chars[mod] + result
        long_value = div
    result = b58chars[long_value] + result
    nPad = 0
    for c in v:
        if c == '\0': nPad += 1
        else: break
    return (b58chars[0]*nPad) + result

def hash_160_to_bc_address(h160, version=settings['ADDRESSVERSION']):
    print 'hash_160_to_bc_address'
    vh160 = version + h160
    h3 = hash256(vh160)
    addr = vh160 + h3[0:4]
    return b58encode(addr)

def deser_string(f):
    print 'deser_string'
    nit = struct.unpack("<B", f.read(1))[0]
    if nit == 253:
        nit = struct.unpack("<H", f.read(2))[0]
    elif nit == 254:
        nit = struct.unpack("<I", f.read(4))[0]
    elif nit == 255:
        nit = struct.unpack("<Q", f.read(8))[0]
    return f.read(nit)

def ser_string(s):
    print 'ser_string'
    if len(s) < 253:
        return chr(len(s)) + s
    elif len(s) < 0x10000:
        return chr(253) + struct.pack("<H", len(s)) + s
    elif len(s) < 0x100000000L:
        return chr(254) + struct.pack("<I", len(s)) + s
    return chr(255) + struct.pack("<Q", len(s)) + s

def deser_uint256(f):
    print 'deser_uint256'
    r = 0L
    for i in xrange(8):
        t = struct.unpack("<I", f.read(4))[0]
        r += t << (i * 32)
    return r

def ser_uint256(u):
    print 'ser_uint256'
    rs = ""
    for i in xrange(8):
        rs += struct.pack("<I", u & 0xFFFFFFFFL)
        u >>= 32
    return rs

def uint256_from_str(s):
    print 'uint256_from_str'
    r = 0L
    t = struct.unpack("<IIIIIIII", s[:32])
    for i in xrange(8):
        r += t[i] << (i * 32)
    return r

def uint256_from_compact(c):
    print 'uint256_from_compact'
    nbytes = (c >> 24) & 0xFF
    v = (c & 0xFFFFFFL) << (8 * (nbytes - 3))
    return v

def deser_vector(f, c):
    print 'deser_vector'
    nit = struct.unpack("<B", f.read(1))[0]
    if nit == 253:
        nit = struct.unpack("<H", f.read(2))[0]
    elif nit == 254:
        nit = struct.unpack("<I", f.read(4))[0]
    elif nit == 255:
        nit = struct.unpack("<Q", f.read(8))[0]
    r = []
    for i in xrange(nit):
        t = c()
        t.deserialize(f)
        r.append(t)
    return r

def ser_vector(l):
    print 'ser_vector'
    r = ""
    if len(l) < 253:
        r = chr(len(l))
    elif len(l) < 0x10000:
        r = chr(253) + struct.pack("<H", len(l))
    elif len(l) < 0x100000000L:
        r = chr(254) + struct.pack("<I", len(l))
    else:
        r = chr(255) + struct.pack("<Q", len(l))
    for i in l:
        r += i.serialize()
    return r

def deser_uint256_vector(f):
    print 'deser_uint256_vector'
    nit = struct.unpack("<B", f.read(1))[0]
    if nit == 253:
        nit = struct.unpack("<H", f.read(2))[0]
    elif nit == 254:
        nit = struct.unpack("<I", f.read(4))[0]
    elif nit == 255:
        nit = struct.unpack("<Q", f.read(8))[0]
    r = []
    for i in xrange(nit):
        t = deser_uint256(f)
        r.append(t)
    return r

def ser_uint256_vector(l):
    print 'ser_uint256_vector'
    r = ""
    if len(l) < 253:
        r = chr(len(l))
    elif len(s) < 0x10000:
        r = chr(253) + struct.pack("<H", len(l))
    elif len(s) < 0x100000000L:
        r = chr(254) + struct.pack("<I", len(l))
    else:
        r = chr(255) + struct.pack("<Q", len(l))
    for i in l:
        r += ser_uint256(i)
    return r

def deser_string_vector(f):
    print 'deser_string_vector'
    nit = struct.unpack("<B", f.read(1))[0]
    if nit == 253:
        nit = struct.unpack("<H", f.read(2))[0]
    elif nit == 254:
        nit = struct.unpack("<I", f.read(4))[0]
    elif nit == 255:
        nit = struct.unpack("<Q", f.read(8))[0]
    r = []
    for i in xrange(nit):
        t = deser_string(f)
        r.append(t)
    return r

def ser_string_vector(l):
    print 'ser_string_vector'
    r = ""
    if len(l) < 253:
        r = chr(len(l))
    elif len(s) < 0x10000:
        r = chr(253) + struct.pack("<H", len(l))
    elif len(s) < 0x100000000L:
        r = chr(254) + struct.pack("<I", len(l))
    else:
        r = chr(255) + struct.pack("<Q", len(l))
    for sv in l:
        r += ser_string(sv)
    return r

def deser_int_vector(f):
    print 'deser_int_vector'
    nit = struct.unpack("<B", f.read(1))[0]
    if nit == 253:
        nit = struct.unpack("<H", f.read(2))[0]
    elif nit == 254:
        nit = struct.unpack("<I", f.read(4))[0]
    elif nit == 255:
        nit = struct.unpack("<Q", f.read(8))[0]
    r = []
    for i in xrange(nit):
        t = struct.unpack("<i", f.read(4))[0]
        r.append(t)
    return r

def ser_int_vector(l):
    print 'ser_int_vector'
    r = ""
    if len(l) < 253:
        r = chr(len(l))
    elif len(s) < 0x10000:
        r = chr(253) + struct.pack("<H", len(l))
    elif len(s) < 0x100000000L:
        r = chr(254) + struct.pack("<I", len(l))
    else:
        r = chr(255) + struct.pack("<Q", len(l))
    for i in l:
        r += struct.pack("<i", i)
    return r

def show_debug_msg(msg):
    if settings['debug']:
        print '{"sniffer":"'+msg+'"}'

class CAddress(object):
    def __init__(self):
        print 'CAddress.__init__'
        self.nServices = 1
        self.pchReserved = settings['ADDRESSVERSION'] * 10 + "\xff" * 2
        self.ip = "0.0.0.0"
        self.port = 0
    def deserialize(self, f):
        print 'CAddress.deserialize'
        self.nServices = struct.unpack("<Q", f.read(8))[0]
        self.pchReserved = f.read(12)
        self.ip = socket.inet_ntoa(f.read(4))
        self.port = struct.unpack(">H", f.read(2))[0]
    def serialize(self):
        print 'CAddress.serialize'
        r = ""
        r += struct.pack("<Q", self.nServices)
        r += self.pchReserved
        r += socket.inet_aton(self.ip)
        r += struct.pack(">H", self.port)
        return r
    def __repr__(self):
        print 'CAddress.__repr__'
        return "CAddress(nServices=%i ip=%s port=%i)" % (self.nServices, self.ip, self.port)

class CInv(object):
    typemap = {
        0: "Error",
        1: "TX",
        2: "Block"}
    def __init__(self):
        print 'CInv.__init__'
        self.type = 0
        self.hash = 0L
    def deserialize(self, f):
        print 'CInv.deserialize'
        self.type = struct.unpack("<i", f.read(4))[0]
        self.hash = deser_uint256(f)
    def serialize(self):
        print 'CInv.serialize'
        r = ""
        r += struct.pack("<i", self.type)
        r += ser_uint256(self.hash)
        return r
    def __repr__(self):
        print 'CInv.__repr__'
        return "CInv(type=%s hash=%064x)" % (self.typemap[self.type], self.hash)

class CBlockLocator(object):
    def __init__(self):
        print 'CBlockLocator.__init__'
        self.nVersion = MY_VERSION
        self.vHave = []
    def deserialize(self, f):
        print 'CBlockLocator.deserialize'
        self.nVersion = struct.unpack("<i", f.read(4))[0]
        self.vHave = deser_uint256_vector(f)
    def serialize(self):
        print 'CBlockLocator.serialize'
        r = ""
        r += struct.pack("<i", self.nVersion)
        r += ser_uint256_vector(self.vHave)
        return r
    def __repr__(self):
        print 'CBlockLocator.__repr__'
        return "CBlockLocator(nVersion=%i vHave=%s)" % (self.nVersion, repr(self.vHave))

class COutPoint(object):
    def __init__(self):
        print 'COutPoint.__init__'
        self.hash = 0
        self.n = 0
    def deserialize(self, f):
        print 'COutPoint.deserialize'
        self.hash = deser_uint256(f)
        self.n = struct.unpack("<I", f.read(4))[0]
    def serialize(self):
        print 'COutPoint.serialize'
        r = ""
        r += ser_uint256(self.hash)
        r += struct.pack("<I", self.n)
        return r
    def __repr__(self):
        print 'COutPoint.__repr__'
        return "COutPoint(hash=%064x n=%i)" % (self.hash, self.n)

class CTxIn(object):
    def __init__(self):
        print 'CTxIn.__init__'
        self.prevout = COutPoint()
        self.scriptSig = ""
        self.nSequence = 0
    def deserialize(self, f):
        print 'CTxIn.deserialize'
        self.prevout = COutPoint()
        self.prevout.deserialize(f)
        self.scriptSig = deser_string(f)
        self.nSequence = struct.unpack("<I", f.read(4))[0]
    def serialize(self):
        print 'CTxIn.serialize'
        r = ""
        r += self.prevout.serialize()
        r += ser_string(self.scriptSig)
        r += struct.pack("<I", self.nSequence)
        return r
    def __repr__(self):
        print 'CTxIn.__repr__'
        return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" % (repr(self.prevout), binascii.hexlify(self.scriptSig), self.nSequence)

class CTxOut(object):
    def __init__(self):
        print 'CTxOut.__init__'
        self.nValue = 0
        self.scriptPubKey = ""
        self.amount = 0
    def deserialize(self, f):
        print 'CTxOut.deserialize'
        self.nValue = struct.unpack("<q", f.read(8))[0]
        self.scriptPubKey = deser_string(f)
        self.amount = float(self.nValue / 1e8)
        self.address = self.build_address()
    def build_address(self):
        print 'CTxOut.build_address'
        return hash_160_to_bc_address(self.scriptPubKey[3:23])
    def serialize(self):
        print 'CTxOut.serialize'
        r = ""
        r += struct.pack("<q", self.nValue)
        r += ser_string(self.scriptPubKey)
        return r
    def __repr__(self):
        print 'CTxOut.__repr__'
        return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" % (self.nValue // 100000000, self.nValue % 100000000, binascii.hexlify(self.scriptPubKey))

class CTransaction(object):
    def __init__(self):
        print 'CTransaction.__init__'
        self.nVersion = 1
        self.vin = []
        self.vout = []
        self.nLockTime = 0
        self.sha256 = None
        self.hash = None
    def deserialize(self, f):
        print 'CTransaction.deserialize'
        self.nVersion = struct.unpack("<i", f.read(4))[0]
        self.vin = deser_vector(f, CTxIn)
        self.vout = deser_vector(f, CTxOut)
        self.nLockTime = struct.unpack("<I", f.read(4))[0]
    def serialize(self):
        print 'CTransaction.serialize'
        r = ""
        r += struct.pack("<i", self.nVersion)
        r += ser_vector(self.vin)
        r += ser_vector(self.vout)
        r += struct.pack("<I", self.nLockTime)
        return r
    def calc_sha256(self):
        print 'CTransaction.calc_sha256'
        if self.sha256 is None:
            self.sha256 = uint256_from_str(hash256(self.serialize()))
        self.hash = hash256(self.serialize())[::-1].encode('hex_codec')
    def is_valid(self):
        print 'CTransaction.is_valid'
        self.calc_sha256()
        for tout in self.vout:
            if tout.nValue < 0 or tout.nValue > 21000000L * 100000000L:
                return False
        return True
    def __repr__(self):
        print 'CTransaction.__repr__'
        return "CTransaction(nVersion=%i vin=%s vout=%s nLockTime=%i)" % (self.nVersion, repr(self.vin), repr(self.vout), self.nLockTime)

class CBlock(object):
    def __init__(self):
        print 'CBlock.__init__'
        self.nVersion = 1
        self.hashPrevBlock = 0
        self.hashMerkleRoot = 0
        self.nTime = 0
        self.nBits = 0
        self.nNonce = 0
        self.vtx = []
        self.sha256 = None
        self.hash = None
    def deserialize(self, f):
        print 'CBlock.deserialize'
        self.nVersion = struct.unpack("<i", f.read(4))[0]
        self.hashPrevBlock = deser_uint256(f)
        self.hashMerkleRoot = deser_uint256(f)
        self.nTime = struct.unpack("<I", f.read(4))[0]
        self.nBits = struct.unpack("<I", f.read(4))[0]
        self.nNonce = struct.unpack("<I", f.read(4))[0]
        self.vtx = deser_vector(f, CTransaction)
    def serialize(self):
        print 'CBlock.serialize'
        r = ""
        r += struct.pack("<i", self.nVersion)
        r += ser_uint256(self.hashPrevBlock)
        r += ser_uint256(self.hashMerkleRoot)
        r += struct.pack("<I", self.nTime)
        r += struct.pack("<I", self.nBits)
        r += struct.pack("<I", self.nNonce)
        r += ser_vector(self.vtx)
        return r
    def calc_sha256(self):
        print 'CBlock.calc_sha256'
        if self.sha256 is None:
            r = ""
            r += struct.pack("<i", self.nVersion)
            r += ser_uint256(self.hashPrevBlock)
            r += ser_uint256(self.hashMerkleRoot)
            r += struct.pack("<I", self.nTime)
            r += struct.pack("<I", self.nBits)
            r += struct.pack("<I", self.nNonce)
            self.sha256 = uint256_from_str(hash256(r))
            self.hash = hash256(r)[::-1].encode('hex_codec')
    def is_valid(self):
        print 'is_valid'
        self.calc_sha256()
        target = uint256_from_compact(self.nBits)
        if self.sha256 > target:
            return False
        hashes = []
        for tx in self.vtx:
            if not tx.is_valid():
                return False
            tx.calc_sha256()
            hashes.append(ser_uint256(tx.sha256))
        while len(hashes) > 1:
            newhashes = []
            for i in xrange(0, len(hashes), 2):
                i2 = min(i+1, len(hashes)-1)
                newhashes.append(hash256(hashes[i] + hashes[i2]))
            hashes = newhashes
        if uint256_from_str(hashes[0]) != self.hashMerkleRoot:
            return False
        return True
    def __repr__(self):
        print 'CBlock.__repr__'
        return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx))

class CUnsignedAlert(object):
    def __init__(self):
        print 'CUnsignedAlert.__init__'
        self.nVersion = 1
        self.nRelayUntil = 0
        self.nExpiration = 0
        self.nID = 0
        self.nCancel = 0
        self.setCancel = []
        self.nMinVer = 0
        self.nMaxVer = 0
        self.setSubVer = []
        self.nPriority = 0
        self.strComment = ""
        self.strStatusBar = ""
        self.strReserved = ""
    def deserialize(self, f):
        print 'CUnsignedAlert.deserialize'
        self.nVersion = struct.unpack("<i", f.read(4))[0]
        self.nRelayUntil = struct.unpack("<q", f.read(8))[0]
        self.nExpiration = struct.unpack("<q", f.read(8))[0]
        self.nID = struct.unpack("<i", f.read(4))[0]
        self.nCancel = struct.unpack("<i", f.read(4))[0]
        self.setCancel = deser_int_vector(f)
        self.nMinVer = struct.unpack("<i", f.read(4))[0]
        self.nMaxVer = struct.unpack("<i", f.read(4))[0]
        self.setSubVer = deser_string_vector(f)
        self.nPriority = struct.unpack("<i", f.read(4))[0]
        self.strComment = deser_string(f)
        self.strStatusBar = deser_string(f)
        self.strReserved = deser_string(f)
    def serialize(self):
        print 'CUnsignedAlert.serialize'
        r = ""
        r += struct.pack("<i", self.nVersion)
        r += struct.pack("<q", self.nRelayUntil)
        r += struct.pack("<q", self.nExpiration)
        r += struct.pack("<i", self.nID)
        r += struct.pack("<i", self.nCancel)
        r += ser_int_vector(self.setCancel)
        r += struct.pack("<i", self.nMinVer)
        r += struct.pack("<i", self.nMaxVer)
        r += ser_string_vector(self.setSubVer)
        r += struct.pack("<i", self.nPriority)
        r += ser_string(self.strComment)
        r += ser_string(self.strStatusBar)
        r += ser_string(self.strReserved)
        return r
    def __repr__(self):
        print 'CUnsignedAlert.__repr__'
        return "CUnsignedAlert(nVersion %d, nRelayUntil %d, nExpiration %d, nID %d, nCancel %d, nMinVer %d, nMaxVer %d, nPriority %d, strComment %s, strStatusBar %s, strReserved %s)" % (self.nVersion, self.nRelayUntil, self.nExpiration, self.nID, self.nCancel, self.nMinVer, self.nMaxVer, self.nPriority, self.strComment, self.strStatusBar, self.strReserved)

class CAlert(object):
    def __init__(self):
        print 'CAlert.__init__'
        self.vchMsg = ""
        self.vchSig = ""
    def deserialize(self, f):
        print 'CAlert.deserialize'
        self.vchMsg = deser_string(f)
        self.vchSig = deser_string(f)
    def serialize(self):
        print 'CAlert.serialize'
        r = ""
        r += ser_string(self.vchMsg)
        r += ser_string(self.vchSig)
        return r
    def __repr__(self):
        print 'CAlert.__repr__'
        return "CAlert(vchMsg.sz %d, vchSig.sz %d)" % (len(self.vchMsg), len(self.vchSig))

class msg_version(object):
    command = "version"
    def __init__(self):
        print 'msg_version.__init__'
        self.nVersion = MY_VERSION
        self.nServices = 1
        self.nTime = time.time()
        self.addrTo = CAddress()
        self.addrFrom = CAddress()
        self.nNonce = random.getrandbits(64)
        self.strSubVer = MY_SUBVERSION
        self.nStartingHeight = -1
    def deserialize(self, f):
        print 'msg_version.deserialize'
        self.nVersion = struct.unpack("<i", f.read(4))[0]
        if self.nVersion == 10300:
            self.nVersion = 300
        self.nServices = struct.unpack("<Q", f.read(8))[0]
        self.nTime = struct.unpack("<q", f.read(8))[0]
        self.addrTo = CAddress()
        self.addrTo.deserialize(f)
        if self.nVersion >= 106:
            self.addrFrom = CAddress()
            self.addrFrom.deserialize(f)
            self.nNonce = struct.unpack("<Q", f.read(8))[0]
            self.strSubVer = deser_string(f)
            if self.nVersion >= 209:
                self.nStartingHeight = struct.unpack("<i", f.read(4))[0]
            else:
                self.nStartingHeight = None
        else:
            self.addrFrom = None
            self.nNonce = None
            self.strSubVer = None
            self.nStartingHeight = None
    def serialize(self):
        print 'msg_version.serialize'
        r = ""
        r += struct.pack("<i", self.nVersion)
        r += struct.pack("<Q", self.nServices)
        r += struct.pack("<q", self.nTime)
        r += self.addrTo.serialize()
        r += self.addrFrom.serialize()
        r += struct.pack("<Q", self.nNonce)
        r += ser_string(self.strSubVer)
        r += struct.pack("<i", self.nStartingHeight)
        return r
    def __repr__(self):
        print 'msg_version.__repr__'
        return "msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i)" % (self.nVersion, self.nServices, time.ctime(self.nTime), repr(self.addrTo), repr(self.addrFrom), self.nNonce, self.strSubVer, self.nStartingHeight)

class msg_verack(object):
    command = "verack"
    def __init__(self):
        print 'msg_verack.__init__'
        pass
    def deserialize(self, f):
        print 'msg_verack.deserialize'
        pass
    def serialize(self):
        print 'msg_verack.serialize'
        return ""
    def __repr__(self):
        print 'msg_verack.__repr__'
        return "msg_verack()"

class msg_addr(object):
    command = "addr"
    def __init__(self):
        print 'msg_addr.__init__'
        self.addrs = []
    def deserialize(self, f):
        print 'msg_addr.deserialize'
        self.addrs = deser_vector(f, CAddress)
    def serialize(self):
        print 'msg_addr.serialize'
        return ser_vector(self.addrs)
    def __repr__(self):
        print 'msg_addr.__repr__'
        return "msg_addr(addrs=%s)" % (repr(self.addrs))

class msg_alert(object):
    command = "alert"
    def __init__(self):
        print 'msg_alert.__init__'
        self.alert = CAlert()
    def deserialize(self, f):
        print 'msg_alert.deserialize'
        self.alert = CAlert()
        self.alert.deserialize(f)
    def serialize(self):
        print 'msg_alert.serialize'
        r = ""
        r += self.alert.serialize()
        return r
    def __repr__(self):
        print 'msg_alert.__repr__'
        return "msg_alert(alert=%s)" % (repr(self.alert), )

class msg_inv(object):
    command = "inv"
    def __init__(self):
        print 'msg_inv.__init__'
        self.inv = []
    def deserialize(self, f):
        print 'msg_inv.deserialize'
        self.inv = deser_vector(f, CInv)
    def serialize(self):
        print 'msg_inv.serialize'
        return ser_vector(self.inv)
    def __repr__(self):
        print 'msg_inv.__repr__'
        return "msg_inv(inv=%s)" % (repr(self.inv))

class msg_getdata(object):
    command = "getdata"
    def __init__(self):
        print 'msg_getdata.__init__'
        self.inv = []
    def deserialize(self, f):
        print 'msg_getdata.deserialize'
        self.inv = deser_vector(f, CInv)
    def serialize(self):
        print 'msg_getdata.serialize'
        return ser_vector(self.inv)
    def __repr__(self):
        print 'msg_getdata.__repr__'
        return "msg_getdata(inv=%s)" % (repr(self.inv))

class msg_getblocks(object):
    command = "getblocks"
    def __init__(self):
        print 'msg_getblocks.__init__'
        self.locator = CBlockLocator()
        self.hashstop = 0L
    def deserialize(self, f):
        print 'msg_getblocks.deserialize'
        self.locator = CBlockLocator()
        self.locator.deserialize(f)
        self.hashstop = deser_uint256(f)
    def serialize(self):
        print 'msg_getblocks.serialize'
        r = ""
        r += self.locator.serialize()
        r += ser_uint256(self.hashstop)
        return r
    def __repr__(self):
        print 'msg_getblocks.__repr__'
        return "msg_getblocks(locator=%s hashstop=%064x)" % (repr(self.locator), self.hashstop)

class msg_tx(object):
    command = "tx"
    def __init__(self):
        print 'msg_tx.__init__'
        self.tx = CTransaction()
    def deserialize(self, f):
        print 'msg_tx.deserialize'
        self.tx.deserialize(f)
    def serialize(self):
        print 'msg_tx.serialize'
        return self.tx.serialize()
    def __repr__(self):
        print 'msg_tx.__repr__'
        return "msg_tx(tx=%s)" % (repr(self.tx))

class msg_block(object):
    command = "block"
    def __init__(self):
        print 'msg_block.__init__'
        self.block = CBlock()
    def deserialize(self, f):
        print 'msg_block.deserialize'
        self.block.deserialize(f)
    def serialize(self):
        print 'msg_block.serialize'
        return self.block.serialize()
    def __repr__(self):
        print 'msg_block.__repr__'
        return "msg_block(block=%s)" % (repr(self.block))

class msg_getaddr(object):
    command = "getaddr"
    def __init__(self):
        print 'msg_getaddr.__init__'
        pass
    def deserialize(self, f):
        print 'msg_getaddr.deserialize'
        pass
    def serialize(self):
        print 'msg_getaddr.serialize'
        return ""
    def __repr__(self):
        print 'msg_getaddr.__repr__'
        return "msg_getaddr()"

#msg_checkorder
#msg_submitorder
#msg_reply

class msg_ping(object):
    command = "ping"
    def __init__(self):
        pass
    def deserialize(self, f):
        pass
    def serialize(self):
        return ""
    def __repr__(self):
        return "msg_ping()"

class NodeConn(asyncore.dispatcher):
    messagemap = {
        "version": msg_version,
        "verack": msg_verack,
        "addr": msg_addr,
        "alert": msg_alert,
        "inv": msg_inv,
        "getdata": msg_getdata,
        "getblocks": msg_getblocks,
        "tx": msg_tx,
        "block": msg_block,
        "getaddr": msg_getaddr,
        "ping": msg_ping
    }
    def __init__(self, dstaddr, dstport):
        print 'NodeConn.__init__'
        asyncore.dispatcher.__init__(self)
        self.dstaddr = dstaddr
        self.dstport = dstport
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sendbuf = ""
        self.recvbuf = ""
        self.ver_send = 209
        self.ver_recv = 209
        self.last_sent = 0
        self.state = "connecting"

        #stuff version msg into sendbuf
        vt = msg_version()
        vt.addrTo.ip = self.dstaddr
        vt.addrTo.port = self.dstport
        vt.addrFrom.ip = "0.0.0.0"
        vt.addrFrom.port = 0
        self.send_message(vt, True)
        print '{"sniffer":"'+settings['host']+':'+str(settings['port'])+'"}'
        try:
            self.connect((dstaddr, dstport))
        except:
            self.handle_close()
    def handle_connect(self):
        print 'NodeConn.handle_connect'
        print '{"sniffer":"Connected"}'
        self.state = "connected"
    def handle_close(self):
        print 'NodeConn.handle_close'
        print '{"sniffer":"Closing"}'
        self.state = "closed"
        self.recvbuf = ""
        self.sendbuf = ""
        try:
            self.close()
        except:
            pass
    def handle_read(self):
        print 'NodeConn.handle_read'
        try:
            t = self.recv(8192)
        except:
            self.handle_close()
            return
        if len(t) == 0:
            self.handle_close()
            return
        self.recvbuf += t
        self.got_data()
    def readable(self):
        print 'NodeConn.readable'
        return True
    def writable(self):
        print 'NodeConn.writable'
        return (len(self.sendbuf) > 0)
    def handle_write(self):
        try:
            sent = self.send(self.sendbuf)
        except:
            self.handle_close()
            return
        self.sendbuf = self.sendbuf[sent:]
    def got_data(self):
        print 'NodeConn.got_data'
        while True:
            if len(self.recvbuf) < 4:
                return
            if self.recvbuf[:4] != settings['MSGHEADER']:
                raise ValueError("got garbage %s" % repr(self.recvbuf))
            if self.ver_recv < 209:
                if len(self.recvbuf) < 4 + 12 + 4:
                    return
                command = self.recvbuf[4:4+12].split(settings['ADDRESSVERSION'], 1)[0]
                msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
                checksum = None
                if len(self.recvbuf) < 4 + 12 + 4 + msglen:
                    return
                msg = self.recvbuf[4+12+4:4+12+4+msglen]
                self.recvbuf = self.recvbuf[4+12+4+msglen:]
            else:
                if len(self.recvbuf) < 4 + 12 + 4 + 4:
                    return
                command = self.recvbuf[4:4+12].split(settings['ADDRESSVERSION'], 1)[0]
                msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
                checksum = self.recvbuf[4+12+4:4+12+4+4]
                if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
                    return
                msg = self.recvbuf[4+12+4+4:4+12+4+4+msglen]
                th = sha256(msg)
                h = sha256(th)
                if checksum != h[:4]:
                    raise ValueError("got bad checksum %s" % repr(self.recvbuf))
                self.recvbuf = self.recvbuf[4+12+4+4+msglen:]
            if command in self.messagemap:
                f = cStringIO.StringIO(msg)
                t = self.messagemap[command]()
                t.deserialize(f)
                self.got_message(t)
            else:
                show_debug_msg("Unknown command: '" + command + "' " + repr(msg))
    def send_message(self, message, pushbuf=False):
        print 'NodeConn.send_message'
        if self.state != "connected" and not pushbuf:
            return
        show_debug_msg("Send %s" % repr(message))
        command = message.command
        data = message.serialize()
        tmsg = settings['MSGHEADER']
        tmsg += command
        tmsg += settings['ADDRESSVERSION'] * (12 - len(command))
        tmsg += struct.pack("<I", len(data))
        if self.ver_send >= 209:
            th = sha256(data)
            h = sha256(th)
            tmsg += h[:4]
        tmsg += data
        self.sendbuf += tmsg
        self.last_sent = time.time()
    def got_message(self, message):
        print 'NodeConn.got_message'
        if self.last_sent + 30 * 60 < time.time():
            self.send_message(msg_ping())
        show_debug_msg("Recv %s" % repr(message))
        if message.command  == "version":
            if message.nVersion >= 209:
                self.send_message(msg_verack())
            self.ver_send = min(MY_VERSION, message.nVersion)
            if message.nVersion < 209:
                self.ver_recv = self.ver_send
        elif message.command == "verack":
            self.ver_recv = self.ver_send
        elif message.command == "inv":
            want = msg_getdata()
            for i in message.inv:
                if i.type == 1:
                    want.inv.append(i)
                elif i.type == 2:
                    want.inv.append(i)
            if len(want.inv):
                self.send_message(want)
        elif message.command == "tx":
            new_transaction_event(message.tx)

        elif message.command == "block":
            new_block_event(message.block)

if __name__ == '__main__':
    if len(sys.argv) == 2:
        f = open(sys.argv[1])
        for line in f:
            m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
            if m is None:
                continue
            settings[m.group(1)] = m.group(2)
        f.close()
    settings['port'] = int(settings['port'])
    c = NodeConn(settings['host'], settings['port'])
    asyncore.loop()

tx.vout (where is) asm and hex

in each tx.vout is there a asm and hex?

shouldn't the scriptPubKey contain


   "asm": "OP_DUP OP_HASH160 2544bedede7298fe7cedb3fcd0eb5fa73729eb64 OP_EQUALVERIFY OP_CHECKSIG",
   "hex": "76a9142544bedede7298fe7cedb3fcd0eb5fa73729eb6488ac",
   "reqSigs": 1,
   "type": "pubkeyhash",
   "addresses": [
                    "14Q4MdFGqFbP9WPzz3AXjsdxZC68rCQjj1"
                    ]
                

Insead I see

v��_/{�/k>//��7`HH��

can you please help

Hi,

I download your project through a wget and now i have the .git sitting on my vps and I am trying to unpack the bitcoin-sniffer.git so I can use the files. Do you know what command I should use?

timeout

Bitcoin Network Sniffer v0.0.2


Connecting to Bitcoin Node IP # 173.242.112.53:8333
error: uncaptured python exception, closing channel <main.NodeConn 173.242.112.53:8333 at 0xd5e878> (<class 'socket.error'>:[Errno 110] Connection timed out [/usr/lib64/python2.7/asyncore.py|read|83] [/usr/lib64/python2.7/asyncore.py|handle_read_event|446] [/usr/lib64/python2.7/asyncore.py|handle_connect_event|454])
Closing Conection ... bye :)

Do I need to change something in my firewall for this to work?

I just uploaded sniffer.py to my server
chmod 755 the script then run it...

testnet

how do we listen to testnet

I've tried searching google for a list of testnet ips / nodes but I got nothing whatsoever!

Also tried same ip(s) as main net but with the port set to 8332

get time stamp from addr() message

Hi There,

Could you please suggest me how can I retrieve timestamp from the CAddress class ? I have tried with many things but it seems it does not work.

The addr() message contains maximum 1000 addresses which are also sent with timestamp. I want to retrieve that. I have made changes to your code to be minimalistic as I am only interested in timestamp. I have attached it for your reference. sniffer.txt

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.