So erstellen Sie eine Ping-Nachricht

Ich habe große Probleme damit, herauszufinden, wie ich eine einfache "PING" -Nachricht senden und eine "PONG" -Antwort zurückerhalten kann.

import random
import hashlib
import socket
PEER_IP = "35.187.200.6"
PEER_PORT = 8333

nonce = (random.getrandbits(64)).to_bytes(8, byteorder="little", signed=False)

magic_number = bytes.fromhex("f9beb4d9")
command_name = bytes.fromhex("ping".encode("utf-8").hex() + ("00")*8)
payload_size = (int(len(nonce))).to_bytes(4, byteorder="little", signed=False)
checksum = hashlib.sha256(hashlib.sha256(nonce).digest()).digest()[:4]

final_msg = (
    magic_number
    + command_name
    + payload_size
    + checksum
    + nonce
)

sock = socket.socket()
sock.connect((PEER_IP, PEER_PORT))
sock.send(final_msg)
pong = sock.recv(1024)
print(pong)

Ich folge diesem YouTube- Tutorial und habe die Socket-Schicht selbst hinzugefügt.

Die einzige Antwort, die ich bekomme, ist

b''

Jeder Einblick in das, was ich hier falsch mache, wäre sehr dankbar.

Danke

Ich glaube, Sie müssen eine versionNachricht aushandeln, bevor eine andere Kommunikation stattfinden kann. Außerdem recvbedeutet der Empfang eines Arrays der Länge Null, dass der Socket getrennt wurde.

Antworten (1)

Sie müssen eine versionNachricht senden (und den Korrespondenten erhalten verack), bevor Sie etwas anderes senden. Hier ist eine schnell gepatchte Version Ihres Skripts, das die Versionsmeldung verarbeitet:

import hashlib
import random
import socket
import time
import urllib.request

PEER_IP = "127.0.0.1"
PEER_PORT = 8333

nonce = (random.getrandbits(64)).to_bytes(8, byteorder="little", signed=False)

magic_number = bytes.fromhex("f9beb4d9")
command_name = bytes.fromhex("ping".encode("utf-8").hex() + ("00")*8)
payload_size = (int(len(nonce))).to_bytes(4, byteorder="little", signed=False)
checksum = hashlib.sha256(hashlib.sha256(nonce).digest()).digest()[:4]

pong_msg = (
    magic_number
    + command_name
    + payload_size
    + checksum
    + nonce
)

# Magic bytes, as usual
magic = bytes.fromhex('f9beb4d9')
# Version number (PROTOCOL_VERSION in core)
version = int(70015).to_bytes(4, 'little')
# Random services, we don't care
services = int(1).to_bytes(8, 'little')
timestamp = int(time.time()).to_bytes(8, 'little')
myip_str = urllib.request.urlopen('https://api.ipify.org').read().decode()
myip = socket.inet_aton(myip_str)
nodeip = socket.inet_aton(PEER_IP)
# https://en.bitcoin.it/wiki/Protocol_documentation#Network_address
addr_recv = services + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'
addr_recv += nodeip + int(8333).to_bytes(2, 'big')
addr_from = services + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'
addr_from += myip + int(8333).to_bytes(2, 'big')
nonce = 0x00.to_bytes(8, 'little')
# You can replace this with something more fun
user_agent = 0x00.to_bytes(1, 'big')
# Let's say zero, once again we don't care for this example
start_height = 0x00.to_bytes(4, 'little')
# The message content, which we'll compute the checksum from
payload = version + services + timestamp + addr_recv + addr_from + nonce
payload += user_agent + start_height
checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
payload_length = len(payload)
# The command type, as NULL padded ascii
version_message = magic + 'version'.encode('ascii') + b'\x00\x00\x00\x00\x00'
version_message += payload_length.to_bytes(4, 'little') + checksum + payload

sock = socket.socket()
sock.connect((PEER_IP, PEER_PORT))
print('Sending version message..',)
sock.send(version_message)
print('Received verack: {}'.format(sock.recv(24)), end='\n\n')
print('Sending ping..')
sock.send(pong_msg)
print('Received pong: {}'.format(sock.recv(1024)))

Und hier ist eine Beispielausgabe meines Knotens:

Sending version message..
Received verack: b'\xf9\xbe\xb4\xd9version\x00\x00\x00\x00\x00h\x00\x00\x00n\x8a\xbe\xc7'

Sending ping..
Received pong: b'\x7f\x11\x01\x00\r\x04\x00\x00\x00\x00\x00\x00\x86\xc5\x08^\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\r\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\xa0vQ\x16V\xb1\xab\x12/Satoshi:0.19.0.1/\x14P\t\x00\x01\xf9\xbe\xb4\xd9verack\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\xf6\xe0\xe2'

Hier ist die Protokolldokumentation , auf die Sie sich bei der Implementierung von Protokollnachrichten verlassen können.

Super, vielen Dank für deine Hilfe. Sehr geschätzt.