p2p

ネットワークプロトコルを使用してブロックヘッダーを要求、受信、検証している
最初の4bytesは常に同じでネットワークマジックと呼ばれる(通信が中断した場合などに再開の目印になる)
Litecoinノードとbitcoinでは異なるマジックバイト
L bitcoin: 0b110907(testnet)
L bitcoin: f9beb4d9(mainnet)

ネットワークメッセージ
f9beb4d9 – network magic
76657273696f6e00000000 – command
65000000 payload length, 4bytes, little-endian
5f1a69d2 – payload checksum, first 4 bytes of hash256 of payload
7211…01 – payload

bitcoin Protocol documentation
https://en.bitcoin.it/wiki/Protocol_documentation

NETWORK_MAGIC = b'\xf9\xbe\xb4\xd9'
TESTNET_NETWORK_MAGIC = b'\x0b\x11\x09\x07'

class NetworkEnvelop:

    def __init__(self, command, payload, testnet=False):
        self.command = command
        self.palyad = payload
        if testnet:
            self.magic = TESTNET_NETWORK_MAGIC
        else:
            self.magic = NETWORK_MAGIC 

    def __repr__(self):
        return '{}: {}'.format(
            self.command.decode('ascii'),
            self.payload.hex(),
        )

parse

    @classmethod
    def parse(cls, s, testnet=False):
        magic = s.read(4)
        if magic == b'':
            raise IOError('Connection reset!')
        if testnet:
            expected_magic = TESTNET_NETWORK_MAGIC
        else:
            expected_magic = NETWORK_MAGIC
        if magic != expected_magic
            raise SyntaxError('magic is not right {} vs {}'.format(magic.hex(), expected_magic.hex()))
        command = s.read(12)
        command = command.strip(b'\x00')
        payload_length =  little_endian_to_int(s.read(4))
        checksum = s.read(4)
        payload = s.read(payload_length)
        calculated_checksum = hash256(payload)[:4]
        if calculated_checksum != checksum:
            raise IOError('checksum does not match')
        return cls(command, payload, testnet=testnet)

parse sample

from network import NetworkEnvelope
from io import BytesIO
message_hex = 'f9beb4d976657261636b000000000000000000005df6e0e2'
stream = BytesIO(bytes.fromhex(message_hex))
envelope = NetworkEnvelope.parse(stream)
print(envelope.command)
print(envelope.payload)

serialize

    def serialize(self):
        result = self.magic
        result += self.command + b'\x00' * (12 - len(self.command))
        result += int_to_little_endian(len(self.payload), 4)
        result += hash256(self.payload)[:4]
        result += self.payload
        return result