Few days ago I've found this article about using raw Bitcoin protocol and now I'm trying to make my own transaction with Python. But I'm already stuck on sending version message.

I've tried to use code snippets from the article. According to it, this code below should work, but Wireshark can't recognize anything and there's no verack response

import msgUtils
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("NODE_IP_ADDRESS", 8333)) # Shodan search 'port:8333'

sock.recv(1000) # receive version
sock.recv(1000) # receive verack

Maybe it don't work because article was written in 2014 and now it's totally outdated?


The msgUtils.py code didn't work with 64-bit Python due to a bug. I've fixed it, so you can try the updated code. (I'm the author of the article.)


Well, probably there is a mistake, here's a working version, which is based on this code:

import time
import socket
import struct
import random

def makeMessage(cmd, payload):
    magic = "F9BEB4D9".decode("hex") # Main network
    command = cmd + (12 - len(cmd)) * "\00"
    length = struct.pack("I", len(payload))
    check = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
    return magic + command + length + check + payload

def versionMessage():
    version = struct.pack("i", 60002)
    services = struct.pack("Q", 0)
    timestamp = struct.pack("q", time.time())
    addr_recv = struct.pack("Q", 0)
    addr_recv += struct.pack(">16s", "")
    addr_recv += struct.pack(">H", 8333)
    addr_from = struct.pack("Q", 0)
    addr_from += struct.pack(">16s", "")
    addr_from += struct.pack(">H", 8333)
    nonce = struct.pack("Q", random.getrandbits(64))
    user_agent_bytes = struct.pack("B", 0)
    height = struct.pack("i", 0)
    payload = version + services + timestamp + addr_recv + addr_from + nonce +user_agent_bytes + height
    return payload

if __name__ == "__main__":
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(("", 8333))
    sock.send(makeMessage("version", versionMessage()))
    sock.recv(1024) # version
    sock.recv(1024) # verack

Your Answer

