This is the code from https://developer.bitcoin.org/examples/p2p_networking.html on how to retrieve a merkle block:
#!/usr/bin/env python
from time import sleep
from hashlib import sha256
import struct
import sys
network_string = "f9beb4d9".decode("hex") # Mainnet
def send(msg,payload):
## Command is ASCII text, null padded to 12 bytes
command = msg + ( ( 12 - len(msg) ) * "\00" )
## Payload length is a uint32_t
payload_raw = payload.decode("hex")
payload_len = struct.pack("I", len(payload_raw))
## Checksum is first 4 bytes of SHA256(SHA256(<payload>))
checksum = sha256(sha256(payload_raw).digest()).digest()[:4]
sys.stdout.write(
network_string
+ command
+ payload_len
+ checksum
+ payload_raw
)
sys.stdout.flush()
## Create a version message
send("version",
"71110100" # ........................ Protocol Version: 70001
+ "0000000000000000" # ................ Services: Headers Only (SPV)
+ "c6925e5400000000" # ................ Time: 1415484102
+ "00000000000000000000000000000000"
+ "0000ffff7f000001208d" # ............ Receiver IP Address/Port
+ "00000000000000000000000000000000"
+ "0000ffff7f000001208d" # ............ Sender IP Address/Port
+ "0000000000000000" # ................ Nonce (not used here)
+ "1b" # .............................. Bytes in version string
+ "2f426974636f696e2e6f726720457861"
+ "6d706c653a302e392e332f" # .......... Version string
+ "93050500" # ........................ Starting block height: 329107
+ "00" # .............................. Relay transactions: false
)
sleep(1)
send("verack", "")
send("filterload",
"02" # ........ Filter bytes: 2
+ "b50f" # ....... Filter: 1010 1101 1111 0000
+ "0b000000" # ... nHashFuncs: 11
+ "00000000" # ... nTweak: 0/none
+ "00" # ......... nFlags: BLOOM_UPDATE_NONE
)
send("getdata",
"01" # ................................. Number of inventories: 1
+ "03000000" # ........................... Inventory type: filtered block
+ "a4deb66c0d726b0aefb03ed51be407fb"
+ "ad7331c6e8f9eef231b7000000000000" # ... Block header hash
)
But the code above doesn't run, thus I made some amendments (if not the error that 'bytes can't concat to strings' will be displayed) to this part:
sys.stdout.write(
str(network_string)
+ command
+ str(payload_len)
+ str(checksum)
+ str(payload_raw)
)
Thereafter, I ran -bitcoind daemon
before piping the script to Unix netcat command:
# Connect to the Bitcoin Core peer running on localhost
python get-merkle.py | nc localhost 8333 | hd
But to no response.
The expected response is:
7f16c5962e8bd963659c793ce370d95f
093bc7e367117b3c30c1f8fdd0d97287 ... Merkle root
07000000 ........................... Transaction count: 7
04 ................................. Hash count: 4
3612262624047ee87660be1a707519a4
43b1c1ce3d248cbfc6c15870f6c5daa2 ... Hash #1
019f5b01d4195ecbc9398fbf3c3b1fa9
bb3183301d7a1fb3bd174fcfa40a2b65 ... Hash #2
41ed70551dd7e841883ab8f0b16bf041
76b7d1480e4f0af9f3d4c3595768d068 ... Hash #3
20d2a7bc994987302e5b1ac80fc425fe
25f8b63169ea78e68fbaaefa59379bbf ... Hash #4
01 ................................. Flag bytes: 1
1d ................................. Flags: 1 0 1 1 1 0 0 0