Не удалось правильно отправить сообщение «версия»

Несколько дней назад я нашел эту статью об использовании необработанного протокола Биткойн, и теперь я пытаюсь провести свою собственную транзакцию с помощью Python. Но я уже застрял на отправке versionсообщения.

Я попытался использовать фрагменты кода из статьи. Согласно ему, этот код ниже должен работать, но Wireshark ничего не может распознать, и verackответа нет.

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

Может быть, это не работает, потому что статья была написана в 2014 году и сейчас она полностью устарела?

Ответы (2)

Код msgUtils.py не работал с 64-битным Python из-за ошибки. Я исправил это, так что вы можете попробовать обновленный код. (Я автор статьи.)

Ну, наверное, есть ошибка, вот рабочая версия, которая основана на этом коде :

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