Unable to send 'version' message correctly

2

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.send(msgUtils.getVersionMsg())
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?

Sergey Potekhin

Posted 2016-12-30T05:43:39.630

Reputation: 285

Answers

1

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", "127.0.0.1")
    addr_recv += struct.pack(">H", 8333)
    addr_from = struct.pack("Q", 0)
    addr_from += struct.pack(">16s", "127.0.0.1")
    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(("93.170.187.9", 8333))
    sock.send(makeMessage("version", versionMessage()))
    sock.recv(1024) # version
    sock.recv(1024) # verack

Sergey Potekhin

Posted 2016-12-30T05:43:39.630

Reputation: 285

1

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.)

Ken Shirriff

Posted 2016-12-30T05:43:39.630

Reputation: 231