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
Sie müssen eine version
Nachricht 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.
Markus H
version
Nachricht aushandeln, bevor eine andere Kommunikation stattfinden kann. Außerdemrecv
bedeutet der Empfang eines Arrays der Länge Null, dass der Socket getrennt wurde.