Что такое провайдер подключения к блокчейну

27 июля 2023

Провайдер — это то, как web3 общается с блокчейном. Провайдеры принимают запросы JSON-RPC и возвращают ответ. Обычно это делается путем отправки запроса на сервер, основанный на сокетах HTTP или IPC.

Примечание

web3.py поддерживает одного провайдера на экземпляр. Если у вас есть расширенный вариант использования, требующий нескольких поставщиков, создайте и настройте новый экземпляр web3 для каждого подключения.

Если вы уже успешно подключены к своему узлу Ethereum, вы можете пропустить остальную часть раздела «Провайдеры».

Выбор способа подключения к вашему узлу

Большинство узлов имеют различные способы подключения к ним.

Наиболее распространенные способы подключения к вашему узлу:

  • IPC (использует локальную файловую систему: самый быстрый и безопасный)
  • Websockets (работает удаленно, быстрее, чем HTTP)
  • HTTP (поддерживается больше узлов)

Если вы не знаете, как решить, выберите этот способ:

  • Если у вас есть возможность запустить web3.py на том же компьютере, что и узел, выберите IPC.
  • Если вам необходимо подключиться к узлу на другом компьютере, используйте веб-сокеты.
  • Если ваш узел не поддерживает веб-сокеты, используйте HTTP.

У большинства узлов есть способ «отключить» параметры подключения. Мы рекомендуем отключить все варианты подключения, которые вы не используете. Это обеспечивает более безопасную настройку: сокращается количество способов, которыми злоумышленники могут попытаться украсть ваш эфир.

После того, как вы решили, как подключиться, вы указываете детали с помощью Provider. Провайдеры — это классы web3.py, настроенные для нужного типа соединения.

Provider:

  • IPCProvider
  • WebsocketProvider
  • WebsocketProviderV2
  • HTTPProvider
  • AsyncHTTPProvider

Настройка провайдера осуществляется следующим образом:

from web3 import Web3
my_provider = Web3.IPCProvider('/my/node/ipc/path')

После этого осуществляется инициализация экземпляра Web3:

w3 = Web3(my_provider)

Наконец, вы готовы начать работу с web3.py.

Поставщик через переменную среды

В качестве альтернативы вы можете установить переменную среды WEB3_PROVIDER_URI перед запуском скрипта, и web3 сначала будет искать этого провайдера.

Допустимые форматы для этой переменной среды:

  • file:///path/to/node/rpc-json/file.ipc
  • http://192.168.1.2:8545
  • https://node.ontheweb.com
  • ws://127.0.0.1:8546

Ярлыки провайдера автоинициализации

Geth dev Подтверждение полномочий

Чтобы подключиться к экземпляру Proof of Authority со значениями по умолчанию: geth –dev.

from web3.auto.gethdev import w3
# confirm that the connection succeeded
w3.is_connected()
True

Встроенные провайдеры

Web3 поставляется со следующими поставщиками, которые подходят для подключения к локальным и удаленным серверам JSON-RPC.

HTTPProvider

class web3.providers.rpc.HTTPProvider(endpoint_uri[, request_kwargs, session])

Этот провайдер обрабатывает взаимодействие с сервером JSON-RPC на основе HTTP или HTTPS.

  • endpoint_uri должен быть полным URI конечной точки RPC, например 'https://localhost:8545'. Для серверов RPC за соединениями HTTP, работающими через порт 80, и соединениями HTTPS, работающими через порт 443, порт можно не указывать в URI.
  • request_kwargs должен быть словарем аргументов ключевого слова, которые будут передаваться в каждый http/https POST-запрос, сделанный на ваш узел.
  • Session позволяет передать объект requests.Session, инициализированный по желанию.
>>> from web3 import Web3
>>> w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))

Обратите внимание, что вы должны создать только один HTTPProvider с одним и тем же URL-адресом поставщика для каждого процесса python, поскольку HTTPProvider повторно использует базовые сетевые соединения TCP/IP для повышения производительности. Несколько поставщиков HTTP с разными URL-адресами будут работать должным образом.

Под капотом HTTPProvider для выполнения запросов используется библиотека запросов requests python. Если вы хотите изменить способ отправки запросов, вы можете использовать для этого request_kwargs. Обычный вариант использования для этого — увеличение времени ожидания для каждого запроса.

>>> from web3 import Web3
>>> w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545", request_kwargs={'timeout': 60}))

Чтобы настроить размер пула соединений, вы можете передать свой собственный файл requests.Session.

from web3 import Web3
adapter = requests.adapters.HTTPAdapter(pool_connections=20, pool_maxsize=20)
session = requests.Session()
session.mount('http://', adapter)
session.mount('https://', adapter)
w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545", session=session))

IPCProvider

class web3.providers.ipc.IPCProvider( ipc_path = None , testnet = False , timeout = 10 )

Этот провайдер обрабатывает взаимодействие с сервером JSON-RPC на основе IPC Socket.

  • ipc_path - путь файловой системы к сокету IPC:
from web3 import Web3
w3 = Web3(Web3.IPCProvider("~/Library/Ethereum/geth.ipc"))

Если не ipc_pathуказано, будет использоваться значение по умолчанию в зависимости от вашей операционной системы.

  • В Linux и FreeBSD:~/.ethereum/geth.ipc
  • В Mac OS:~/Library/Ethereum/geth.ipc
  • В Windows:\\.\pipe\geth.ipc

WebsocketProvider

Примечание

WebsocketProviderV2 в настоящее время находится в стадии бета-тестирования, и наша цель — полностью заменить WebsocketProvider на WebsocketProviderV2 в следующем крупном выпуске web3.py.

class web3.providers.websocket.WebsocketProvider( endpoint_uri[, websocket_timeout , websocket_kwargs])

Этот провайдер обрабатывает взаимодействие с сервером JSON-RPC на основе WS или WSS.

  • endpoint_uri - полный URI конечной точки RPC, например 'ws://localhost:8546'.
  • websocket_timeout тайм-аут в секундах, используемый при получении или отправке данных по соединению. По умолчанию 10.
  • websocket_kwargs словарь аргументов ключевых слов, которые будут переданы в соединение через веб-сокет ws/wss.
from web3 import Web3
w3 = Web3(Web3.WebsocketProvider("ws://127.0.0.1:8546"))

Под капотом используется WebsocketProvider библиотека веб-сокетов python для выполнения запросов. Если вы хотите изменить способ отправки запросов, вы можете использовать для этого websocket_kwargs.

В отличие от соединений HTTP, время ожидания для соединений WS управляется отдельным websocket_timeout аргументом, как показано ниже.

from web3 import Web3
w3 = Web3(Web3.WebsocketProvider("ws://127.0.0.1:8546", websocket_timeout=60))
WebsocketProviderV2 (бета)
сортweb3.providers.вебсокет. WebsocketProviderV2 ( endpoint_uri , websocket_kwargs , call_timeout )

Этот провайдер обрабатывает взаимодействие с сервером JSON-RPC на основе WS или WSS.

  • endpoint_uri - полный URI конечной точки RPC, например 'ws://localhost:8546'.
  • websocket_kwargs - словарь аргументов ключевых слов, которые будут переданы в соединение через веб-сокет ws/wss.
  • call_timeout - тайм-аут в секундах, используемый при получении или отправке данных по соединению. По умолчанию None(без тайм-аута).
>>> import asyncio
>>> from web3 import AsyncWeb3
>>> from web3.providers import WebsocketProviderV2

>>> LOG = True  # toggle debug logging
>>> if LOG:
    import logging
    logger = logging.getLogger("web3.providers.WebsocketProviderV2")
    logger.setLevel(logging.DEBUG)
    logger.addHandler(logging.StreamHandler())

>>> async def ws_v2_subscription_example():
    async with AsyncWeb3.persistent_websocket(
        WebsocketProviderV2(f"ws://127.0.0.1:8546")
    ) as w3:
        # subscribe to new block headers
        subscription_id = await w3.eth.subscribe("newHeads")

        unsubscribed = False
        while not unsubscribed:
            async for response in w3.listen_to_websocket():
                print(f"{response}\n")
                # handle responses here

                if some_condition:
                    # unsubscribe from new block headers
                    unsubscribed = await w3.eth.unsubscribe(subscription_id)
                    break

        # still an open connection, make any other requests and get
        # responses via send / receive
        latest_block = await w3.eth.get_block("latest")
        print(f"Latest block: {latest_block}")

        # the connection closes automatically when exiting the context
        # manager (the `async with` block)

>>> asyncio.run(ws_v2_subscription_example())

Под капотом используется WebsocketProviderV2 библиотека веб-сокетов python для выполнения запросов. Если вы хотите изменить способ отправки запросов, вы можете использовать для этого websocket_kwargs.

Тайм-аут для каждого вызова на отправку или получение управляется аргументом call_timeout. Установлен None по умолчанию, что означает отсутствие тайм-аута.

Автопровайдер

AutoProvider используется по умолчанию при инициализации web3.Web3 без каких-либо провайдеров. Редко есть причина использовать его явно.

AsyncHTTPProvider

class web3.providers.async_rpc.AsyncHTTPProvider( endpoint_uri[, request_kwargs])

Этот провайдер асинхронно обрабатывает взаимодействие с сервером JSON-RPC на основе HTTP или HTTPS.

  • endpoint_uri - полный URI конечной точки RPC, например 'https://localhost:8545'. Для серверов RPC за соединениями HTTP, работающими через порт 80, и соединениями HTTPS, работающими через порт 443, порт можно не указывать в URI.
  • request_kwargs - словарь аргументов ключевого слова, которые будут передаваться в каждый http/https POST-запрос, сделанный на ваш узел.
  • метод cache_async_session() позволяет вам использовать свой собственный aiohttp.ClientSessionобъект. Это асинхронный метод, а не часть конструктора.
from aiohttp import ClientSession
from web3 import AsyncWeb3, AsyncHTTPProvider

w3 = AsyncWeb3(AsyncHTTPProvider(endpoint_uri))

# If you want to pass in your own session:
custom_session = ClientSession()
await w3.provider.cache_async_session(custom_session) # This method is an async method so it needs to be handled accordingly

Под капотом для выполнения запросов AsyncHTTPProvider используется библиотека python aiohttp.

AsyncHTTPProvider имеет почти все те же функции, что и HTTPProvider. Единственными задокументированными исключениями из этого правила являются:

  • ENS Address Lookup— он еще не может разрешать ENSадреса.
  • Доступное ПО промежуточного слоя . Эти промежуточные ПО имеют асинхронные версии:
      • Attribute Dict Middleware
      • Buffered Gas Estimate Middleware
      • Gas Price Strategy Middleware
      • Geth POA Middleware
      • Local Filter Middleware
      • Simple Cache Middleware
      • Stalecheck Middleware
      • Validation Middleware

EthereumTesterProvider

Предупреждение

Экспериментальный: этот провайдер является экспериментальным. По-прежнему существуют значительные пробелы в функциональности. Однако он активно развивается и поддерживается.

class web3.providers.eth_tester.EthereumTesterProvider( eth_tester = None )

Этот провайдер интегрируется с eth-tester библиотекой. Аргумент eth_tester конструктора должен быть экземпляром EthereumTester или подклассом класса BaseChainBackend, предоставляемого библиотекой eth-tester.

>>> from web3 import Web3, EthereumTesterProvider
>>> w3 = Web3(EthereumTesterProvider())

Примечание

Чтобы установить необходимые зависимости для использования EthereumTesterProvider, вы можете установить дополнительный пакет pip, который имеет правильные интероперабельные версии и eth-tester зависимости py-evm, необходимые для тестирования: напримерpip install web3[tester]