Python 및 TCP 소켓을 사용하는 비트코인 ​​네트워크 프로토콜 소개

블록체인 기술은 분산 노드가 공통 원장을 공유할 수 있도록 하는 합의 알고리즘을 기반으로 합니다. 이러한 알고리즘의 기본적인 종속성은 참여 노드 간의 통신을 가능하게 하는 공통 네트워크 프로토콜입니다. 오늘은 실제 Bitcoin 노드와 상호 작용하는 Python 프로그램을 처음부터 작성해 보겠습니다.

이 게시물은 귀하가 블록체인 기술의 기본 사항에 익숙하다고 가정합니다. 그렇지 않은 경우 Satoshi Nakamoto의 Bitcoin White Paper을 확인하는 것이 좋습니다.

비트코인 노드는 TCP 프로토콜을 사용하여 서로 통신합니다. 노드는 일반적으로 포트 번호 8333에서 수신 대기합니다. 비트코인 ​​네트워크 프로토콜check out this resource에 대한 자세한 설명은 .

오늘 우리는 비트코인 ​​노드에 연결하고 특정 트랜잭션의 세부 정보를 가져오는 Python 프로그램을 작성할 것입니다. 다음은 개발될 메시지 흐름의 다이어그램입니다.



프로그램 코딩을 시작하기 전에 한 가지 사항을 분명히 해야 합니다. 원시 TCP 소켓을 사용하여 Bitcoin 노드와 상호 작용하는 것은 바퀴를 재발명하는 것입니다. 이것은 python-bitcoinlib 과 같은 파이썬 패키지에 의해 이미 수행되었습니다.

정교한 응용 프로그램을 작성하려면 해당 작업에 맞는 도구를 사용해야 합니다. 하지만 TCP 소켓을 사용한 프로그래밍은 네트워크 프로토콜에 대한 낮은 수준의 이해를 향상시키는 좋은 방법입니다.

시작하려면 프로그램에 필요한 종속 항목을 가져오겠습니다.

#!/usr/bin/env python

# Filename:                     bitcoin-network-tutorial.py
# Command to run the program:   python bitcoin-network-tutorial.py

# Import dependencies
import socket
import time
import random
import struct
import hashlib
import binascii

이제 "버전"요청 메시지를 구성하는 데 필요한 메서드를 정의하겠습니다.

# 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 = 0
    payload = struct.pack('<LQQ26s26sQ16sL', version, services, timestamp, addr_peer,
                          addr_local, nonce, create_sub_version(), start_height)
    return(payload)

struct 모듈은 이진 데이터를 압축하는 데 사용됩니다. hashlib 모듈은 메시지 체크섬을 생성하는 데 사용됩니다. 코드를 완전히 이해하려면 데이터 인코딩을 protocol documentation.과 상호 참조해야 합니다.

다음으로 "verack"요청 메시지를 생성하는 메서드를 추가해 보겠습니다. verack 명령 이름은 "버전 확인"에서 파생됩니다.

# Create the "verack" request message
def create_message_verack():
    return bytearray.fromhex("f9beb4d976657261636b000000000000000000005df6e0e2")

필수 메시지를 제거하면 이제 특정 트랜잭션의 세부 정보를 검색하기 위한 "getdata"메서드를 만들 수 있습니다.

# 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)

모든 노드가 임의의 트랜잭션 데이터를 반환할 수 있는 것은 아닙니다. 일부는 디스크 공간을 절약하기 위해 기록을 정리합니다.

또한 TCP 데이터를 터미널에 인쇄하는 방법도 만들 것입니다.

# 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 = "fc57704eff327aecfadb2cf3774edc919ba69aba624b836461ce2be9c00a0c20"
    peer_ip_address = '104.199.184.15'
    peer_tcp_port = 8333
    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.connect((peer_ip_address, peer_tcp_port))

    # Send message "version"
    s.send(version_message)
    response_data = s.recv(buffer_size)
    print_response("version", version_message, response_data)

    # Send message "verack"
    s.send(verack_message)
    response_data = s.recv(buffer_size)
    print_response("verack", verack_message, response_data)

    # Send message "getdata"
    s.send(getdata_message)
    response_data = s.recv(buffer_size)
    print_response("getdata", getdata_message, response_data)

    # Close the TCP connection
    s.close()

Bitnodes.을 사용하여 노드의 IP 주소를 찾았습니다. 쿼리하기로 선택한 트랜잭션의 세부 정보는 block explorer.에서 찾을 수 있습니다.
python bitcoin-network-tutorial.py 명령으로 터미널에서 프로그램을 실행합니다. 아래에 샘플 출력이 나와 있습니다.

Command: version
Request:
b'f9beb4d976657273696f6e000000000064000000f4de76b762ea00000100000000000000c8c6ae5d00000000010000000000000000000000000000000000ffff68c7b80f208d010000000000000000000000000000000000ffff7f000001208d0f2f736a397699b60f2f5361746f7368693a302e372e322f00000000'
Response:
b'f9beb4d976657273696f6e000000000066000000fe4aee167f1101000d04000000000000c2c6ae5d00000000010000000000000000000000000000000000ffff68c7b80f208d0d040000000000000000000000000000000000000000000000000b63185e17ebcdb3102f5361746f7368693a302e31382e302fbc29090001'

Command: verack
Request:
b'f9beb4d976657261636b000000000000000000005df6e0e2'
Response:
b'f9beb4d976657261636b000000000000000000005df6e0e2'

Command: getdata
Request:
b'f9beb4d9676574646174610000000000220000007b00a9b50101fc57704eff327aecfadb2cf3774edc919ba69aba624b836461ce2be9c00a0c20'
Response:
b'f9beb4d9616c65727400000000000000c0000000d2f50d9ef9beb4d9616c65727400000000000000a80000001bf9aaea60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50'

이것으로 튜토리얼을 마칩니다! 더 많은 것을 기대해 주세요.

울트라 구성 생성기



에 대해 들어보셨나요? 그렇지 않은 경우 확인하는 것이 좋습니다.

우리는 네트워크 엔지니어가 매우 유연하고 효율적이며 우아한 방식으로 네트워크 구성을 생성하고 자동화할 수 있도록 제품을 설계했습니다. 우리 고객들은 이 애플리케이션을 좋아하고 여러분도 그렇게 되기를 바랍니다.

다음 시간까지 몸조심하세요!

울트라 구성

좋은 웹페이지 즐겨찾기