I'm trying to make a simple peer connection using Python.
If I understand correctly communication begins by sending a "version" packet to the receiving node. The node then sends back a "verack" packet, afterwards you may begin querying for data/pushing txs.
Ken Shirriff's blog has proved invaluable in getting me this far but I'm unable to get his code examples working, possibly because they're dated?
In particular, when running:
https://github.com/shirriff/bitcoin-code/blob/master/minimalPeerConnection.py
the socket closes immediately. I fail to receive back a "verack" and am unable to proceed with pushing my tx. Note that I've replaced his hard-coded IP with a currently operating node (124.248.237.178:8333).
I've attempted to construct a more "up to date" version packet (70002) referencing these docs but run into the same issue:
import struct
import socket
import time
import hashlib
import binascii
magic = 0xd9b4bef9
def makeMessage(magic,command,payload):
checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[0:4]
return struct.pack('L12sL4s',magic,command,len(payload),checksum).encode("hex")+payload
def makeVersionPayload():
version = 70002
services = 1
timestamp = int(time.time())
adr_u = "::ffff:127.0.0.1"
services_u = 1
port_u = 8333
adr_me = "::ffff:127.0.0.1"
services_me = 1
port_me = 8333
nonce = 0
user_agent_bytes = 0
start_height = 0
relay = 0
#https://bitcoin.org/en/developer-reference#version
payload_hex = "";
payload_hex += struct.pack("<L",version).encode("hex")
payload_hex += struct.pack("<Q",services).encode("hex")
payload_hex += struct.pack("<Q",timestamp).encode("hex")
payload_hex += struct.pack("<Q",services_u).encode("hex")
payload_hex += struct.pack(">16s",adr_u).encode("hex")
payload_hex += struct.pack(">H",port_u).encode("hex")
payload_hex += struct.pack("<Q",services_me).encode("hex")
payload_hex += struct.pack(">16s",adr_me).encode("hex")
payload_hex += struct.pack(">H",port_me).encode("hex")
payload_hex += struct.pack("<Q",nonce).encode("hex")
payload_hex += struct.pack("<B",user_agent_bytes).encode("hex")
payload_hex += struct.pack("<L",start_height).encode("hex")
payload_hex += struct.pack("<B",relay).encode("hex")
return payload_hex
ip = socket.gethostbyname("124.248.237.178")
port = 8333
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "connected to node..."
sock.connect((ip,port))
hex_msg = makeMessage(magic,"version",makeVersionPayload())
print "sending version packet"
sock.send(binascii.unhexlify(hex_msg))
while 1:
msg = sock.recv(4096)
if not msg:
print "disconnected"
exit()
else:
#expecting verack?
print "response: ",msg
Can anyone point me in the right direction?