Browsed by
Category: Uncategorized

Bitpy – compiled!

Bitpy – compiled!

You can now download and run a compiled version of Bitpy (Bitpy0.0.1.exe) from mega.nz.

Just download it from this link.

Or you can copy and paste the link in your browser: https://mega.nz/#!kEMF2bpS!qkXPZBh4BPtaoA9bHz9WIeInE9VaU5QF9EY4XgB35sw

 

Please note that the code and program are intended for educational purposes only. Don’t use with any sensitive device or as a real live Bitcoin client.

Pivot number one – Python 2.7 to 3.5

Pivot number one – Python 2.7 to 3.5

Why did we migrated from Python 2.7 to Python 3.5?

After many discussions and long conversations Alexis and I decided that we should use Python 3. I can’t really point on the exact reason that made us agreed on this change, but I guess the parse_ip bug (As described over here) was the real catalysis. We’ve spent so much time fixing something that worked just fine in python 3. We just snapped, and decided to bite our lips and make the change.

So how will your code base be effected?

Not much actually. We’ve tried our best to keep the changes in the code as minimal as possible. But nevertheless, there’re changes. We’ll add a sub section to each individual post that was published prior to the Python 3.5 migration. In these sub sections we’ll do our best to cover all of the changes in the code. We’re also highly suggesting that you’ll view the full change log in github.

  • Pay attention! The github change log displays all of the changes in the code, included many changes that are nothing more than a draft and changes that aren’t necessarily related to Python 3 migration.

 

Here’s a list of most of the changes that were made in the code during this Python 3.5 migration:

  1. Every print function is now requires parentheses print "hello world" --> print ("hello world").
  2. We’ve fixed the data type – parse_ip bug (described over here).
  3. We’ve added a new data type set of functions called read_hexa and to_hexa which are used for decoding and encoding hexadecimals. (don’t forget, we’re working mostly with strings of bytes, so hexadecimal decoder and encoder are highly important).
  4. we’ve added a try call in Bitpy/Packets/PacketCreator.py .

We also suggest that you’ll read this great article on the general changes between Python 2.x and Python 3.x.

 

Messages part three – Ping Pong and VerAck

Messages part three – Ping Pong and VerAck

VerAck

When establishing connection, we first need to send a version message to the node we wish to connect to. But keeping our connection alive will require the use of 3 more messages: ping, pong and VerAck.

The VerAck message is the most simple type of message, it’s basically an empty message, it has no payload, only a header. Alexis and I have decided that any type of message will have its own file to construct and parse its payload, even if that message doesn’t have any payload. It helps us to maintain the structure of our project.

Bitpy/Packets/control_messages/verack.py:

class EncodeVerack:
    def __init__(self):
        self.command_name = "verack"

    # Verack messages have an empty payload
    def forge(self):
        return ""


# No need this class because, like GetAddr, there is no payload
class DecodeVerack:
    def __init__(self, payload=""):
        pass

As you can see, the function forge will return an empty string and the class DecodeVerAck won’t do anything.

Pay attention that even though the VerAck payload is empty, this message still needs to have a header. The header will contain 4 bytes for the Magic number (or starting string), 12 bytes for the command name (VerAck), 4 bytes for the size of the payload (which in this case will be zero) and another 4 bytes for the checksum (which in this case will always be the same).

 

 

Ping and Pong

One node can always send a ping request to the other. That is how peers on the network can check if the connection is still alive. Ping request is a nothing more than a message, just like any other Bitcoin message, that contains one field:

Size (Bytes) Name Data type Description
8 nonce uint_64 A random number

Alice sends Bob a ping message. This ping message will contain 8 bytes of random number. Bob will receive this ping message from Alice, and will acknowledge her request by sending her a pong message, this pong message will contain the same random number that Alice sent to Bob.

Let’s have a look at the code implementation

Bitpy/Packets/control_messages/ping.py:

import random
from Utils.dataTypes import *


class EncodePing:
    def __init__(self):
        self.command_name = "ping"
        self.nonce = to_uint64(random.getrandbits(64))

    def forge(self):
        return self.nonce


class DecodePing:
    def __init__(self, payload):
        self.nonce = payload.read(8)

When we want to construct a ping message we’ll use the class EncodePing which will set the field nonce to be 8 bytes long random number (64 bit = 8 bytes). When we’ll receive a ping message, we’ll use the class DecodePing with the payload of the incoming message to find out the nonce of that ping message (We’re only reading the nonce in the ping message, we haven’t used it yet). We’ll use this nonce when we’ll construct our returning (pong) message.

 

Bitpy/Packets/control_messages/pong.py:

from Utils.dataTypes import *

class EncodePong:
    def __init__(self, ping_received):
        self.command_name = "pong"

        self.nonce = ping_received

    def forge(self):
        return self.nonce

class DecodedPong:
    def __init__(self, pong_received):
        self.command_name = "pong"
        self.nonce = read_uint64(pong_received.read(8))

    def get_decoded_info(self):
        return "\npong   :\t\t %s" % self.nonce

The class EncodePong will take the payload of the incoming ping message and will assign it to be the nonce of the pong message (the message that we’ll send back). The DecodedPong class will receive the payload of the pong and will assign it to the self variable nonce. We can use the get_decoded_info function to display this nonce number. Because the pong is just a returning message, there’s nothing else we need to do with it.