Skip to main content
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user

I am trying to implement an SPV client in python (for my own learning). I want to start by making a simple TCP connection to a full node, but I either cannot get a response to my version message, or to my verack message if the version message goes through. I have referenced thisthis and this is the code that I am trying to run:

I am trying to implement an SPV client in python (for my own learning). I want to start by making a simple TCP connection to a full node, but I either cannot get a response to my version message, or to my verack message if the version message goes through. I have referenced this and this is the code that I am trying to run:

I am trying to implement an SPV client in python (for my own learning). I want to start by making a simple TCP connection to a full node, but I either cannot get a response to my version message, or to my verack message if the version message goes through. I have referenced this and this is the code that I am trying to run:

Bumped by Community user
Source Link

SPV client TCP connection in python

I am trying to implement an SPV client in python (for my own learning). I want to start by making a simple TCP connection to a full node, but I either cannot get a response to my version message, or to my verack message if the version message goes through. I have referenced this and this is the code that I am trying to run:

#Import dependencies import socket import time import random import struct import hashlib import binascii import ssl import socks # Binary encode the sub-version def create_sub_version(): sub_version = "/Satoshi:0.7.2/" return b'\x0F' + sub_version.encode() # Binary encode the network addresses def create_network_address(ip_address, port): network_address = struct.pack('>8s16sH', b'\x01', bytearray.fromhex("00000000000000000000ffff") + socket.inet_aton(ip_address), port) return(network_address) # Create the TCP request object def create_message(magic, command, payload): checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[0:4] return(struct.pack('L12sL4s', magic, command.encode(), len(payload), checksum) + payload) # Create the "version" request payload def create_payload_version(peer_ip_address): version = 60002 services = 1 timestamp = int(time.time()) addr_local = create_network_address("127.0.0.1", 8333) addr_peer = create_network_address(peer_ip_address, 8333) nonce = random.getrandbits(64) start_height = 645953 payload = struct.pack('<LQQ26s26sQ16sL', version, services, timestamp, addr_peer, addr_local, nonce, create_sub_version(), start_height) return(payload) # Create the "verack" request message def create_message_verack(): return bytearray.fromhex("f9beb4d976657261636b000000000000000000005df6e0e2") # Create the "getdata" request payload def create_payload_getdata(tx_id): count = 1 type = 1 hash = bytearray.fromhex(tx_id) payload = struct.pack('<bb32s', count, type, hash) return(payload) # Print request/response data def print_response(command, request_data, response_data): print("") print("Command: " + command) print("Request:") print(binascii.hexlify(request_data)) print("Response:") print(binascii.hexlify(response_data)) if __name__ == '__main__': # Set constants magic_value = 0xd9b4bef9 tx_id = "a13e7979d3607e187d2ce81ca9fdadfe967b2f3fc1109ce47d46cc09ebd41c50" peer_ip_address = socket.gethostbyname('bitcoin.aranguren.org') peer_tcp_port = 50002 buffer_size = 1024 # Create Request Objects version_payload = create_payload_version(peer_ip_address) version_message = create_message(magic_value, 'version', version_payload) verack_message = create_message_verack() getdata_payload = create_payload_getdata(tx_id) getdata_message = create_message(magic_value, 'getdata', getdata_payload) # Establish TCP Connection s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(10) ws = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1) ws.connect((peer_ip_address, peer_tcp_port)) # Send message "version" ws.send(version_message) response_data = ws.recv(buffer_size) print_response("version", version_message, response_data) # Send message "verack" ws.send(verack_message) response_data = ws.recv(buffer_size) print_response("verack", verack_message, response_data) # Send message "getdata" ws.send(getdata_message) response_data = ws.recv(buffer_size) print_response("getdata", getdata_message, response_data) # Close the TCP connection ws.close() 

The server I connect to in the code is among the only ones that would respond to the version message, returning b'7b226a736f6e727063223a2022322e30222c20226572726f72223a207b22636f6465223a202d33323730302c20226d657373616765223a20226d65737361676573206d75737420626520656e636f64656420696e205554462d38227d2c20226964223a206e756c6c7d0a'.

I also tried referencing: this stack exchange question and Ken Shirriff's github code, but none seem to work, either because I am using python3 or from other causes. I am a beginner in this, so if somebody could help me understand why I cannot get my messages across in the above code or has another implementation in python3, I would be grateful.