Инфраструктура Web3: IPFS, L2 и оракулы
В нашей учебной библиотеке контракт хранит отпечаток выпуска, а браузер умеет читать реестр и отправлять действия редактора. Однако сам текст ещё нужно где-то разместить. Кроме того, приложению могут потребоваться внешние сведения и работа в более дешёвой сети. Разберём эти расширения по отдельности, чтобы каждая новая зависимость получила понятное назначение.
Начнём с публикации содержимого в IPFS. Затем рассмотрим данные оракулов, обмен между сетями и доказательства вычислений. Примеры здесь описывают проектирование и ожидаемые состояния: загрузки, развёртывание, реальные запросы оракулам и исполнения контрактов при подготовке материала не выполнялись.
Адрес содержимого и адрес сервера
Обычный URL задаёт место, в котором запрашивается ресурс. Содержимое по этому адресу может измениться. В IPFS используется адресация по содержимому: CID помогает идентифицировать объект и проверить полученные данные в рамках соответствующего формата. При изменении содержимого меняется и идентификатор соответствующего объекта.
Для одного файла CID не всегда равен привычному шестнадцатеричному SHA-256 исходных байтов. В процессе импорта файл может разбиваться на блоки и представляться графом; CID содержит сведения о формате и хеше конкретного блока. Параметры импорта способны влиять на результирующий корень. Поэтому нельзя скопировать строку CID в поле bytes32, предназначенное для отпечатка документа, и считать задачу решённой.
Наш реестр оставим с прежним назначением: contentHash содержит SHA-256 точных сохранённых байтов манифеста выпуска. Манифест описывает учебные файлы, их пути, размеры и контрольные суммы. После импорта отдельное внешнее досье связывает этот документ с CID манифеста и корнем каталога. Сам манифест не включает корень каталога, внутри которого он находится: так избегаем круговой зависимости идентификаторов.
{
"schema": "library-release-v1",
"courseId": "17",
"edition": "1",
"files": [
{
"path": "lessons/01-introduction.html",
"bytes": "TO_BE_COMPUTED",
"sha256": "TO_BE_COMPUTED"
}
]
}
Это схема с незаполненными контрольными значениями, а не проверенный выпуск. Итоговый читатель отвергает такие пометки. Издатель сначала сохраняет окончательный файл в определённой кодировке, хеширует именно его байты и затем импортирует выпуск. Читатель сначала сопоставляет полученные байты с доверенным отпечатком, затем разбирает JSON; пересериализация до проверки изменила бы предмет сравнения.
CID остаётся самостоятельным адресом IPFS. Его нельзя обрезать до bytes32 или объявить равным SHA-256 манифеста. Подробный порядок подготовки находится в курсе проверяемых выпусков IPFS.
Почему файл может исчезнуть из доступа
IPFS помогает адресовать и передавать содержимое, но не обещает, что неизвестный участник сети будет хранить любой опубликованный файл бесконечно. Кто-то должен сохранять нужные блоки и предоставлять их другим. Pinning закрепляет выбранные данные у конкретного узла или сервиса; он не превращает всю сеть в автоматическую резервную копию.
Для учебной библиотеки понадобятся собственная исходная копия, несколько независимых мест хранения и наблюдение за доступностью. Проверка «файл однажды открылся через мой шлюз» недостаточна. Нужен сценарий, в котором основной поставщик выключен, а читатель получает тот же выпуск через другой путь.
| Слой | Что он обеспечивает | Чего он сам не гарантирует |
|---|---|---|
| CID | Идентификацию объекта | Наличие доступного поставщика |
| Pinning | Сохранение у выбранного хранителя | Независимость от этого хранителя |
| HTTP-шлюз | Удобный доступ из браузера | Что браузер сам проверил все блоки |
| Резервная копия | Возможность восстановить данные | Их постоянную сетевую доступность |
| Реестр публикаций | Объявленный издателем выпуск | Качество или законность текста |
При выборе HTTP-шлюза нужно понять, где выполняется проверка соответствия CID. Обычный браузер, который получил страницу по HTTPS, прежде всего доверяет ответу шлюза в рамках этого соединения. Механизмы получения проверяемых блоков и самостоятельной проверки образуют другой маршрут. Не следует приписывать простой ссылке свойства клиента, которые в ней не реализованы.
Для веб-страниц важна и изоляция origin. Размещение разных сайтов под одним origin по путям может создавать нежелательные отношения между их скриптами и браузерным состоянием. Поддоменные шлюзы помогают изолировать происхождение отдельных CID. Детали зависят от шлюза, формата адреса и возможностей клиента. Описание шлюзов IPFS.
Публичность, имена и JavaScript-клиент
CID не является паролем. Если человек знает идентификатор и может получить данные, он способен сохранить и передать их дальше. Удаление ссылки с сайта или деактивация курса в контракте не заставляет исчезнуть чужие копии. Закрытые материалы требуют отдельной модели шифрования и выдачи ключей; распространённый ключ нельзя отозвать у уже прочитавшего пользователя.
Также не нужно считать сетевые запросы анонимными. Наблюдатель может получать сведения о том, кто запрашивает или предоставляет объекты. Поэтому личные данные и секреты не следует публиковать в учебном каталоге лишь потому, что выбран распределённый протокол. Приватность и шифрование в IPFS.
CID удобно использовать для определённого выпуска. Для изменяемого указателя существуют другие механизмы, например IPNS и DNSLink. Они добавляют владельца имени, обновление записи, сроки и особенности разрешения. Название «последняя версия» полезно читателю, но рядом с ним стоит сохранять точный CID использованного выпуска, иначе повторное открытие страницы может привести к другим данным.
В новых JavaScript-примерах нужно изучать Helia и её актуальные пакеты, а не незаметно устанавливать старый js-ipfs по командам давнего видео. При этом выбрать библиотеку недостаточно: нужно определить постоянное хранилище блоков, способ соединения, ограничения браузера и маршрут получения данных. Одно успешно созданное значение CID ещё не демонстрирует сетевую доступность после закрытия страницы. Проект Helia.
Контракт не открывает внешний API
Предположим, библиотеке нужна справочная цена или результат внешней проверки. Обычный веб-сервер может прочитать API, но контракт не может сделать этот запрос так же, как fetch в браузере. Для доставки внешних данных используется оракул или другая система, которая получает сведения вне цепочки и передаёт их в проверяемой форме.
Важно сформулировать, чему именно мы доверяем: источнику исходных данных, операторам доставки, механизму агрегации, администратору контракта и правилам обновления. Фраза «данные в блокчейне» не отменяет этих зависимостей. Если исходный источник ошибся, согласованная запись ошибочного значения не превращает его в правильное.
Для ценового feed потребитель проверяет подходящую сеть и адрес, смысл пары, количество десятичных знаков и актуальность. Поле answer обычно передаётся как целое значение с масштабом decimals. Например, учебное 123450000 при шести знаках означает 123.45, а не 123450000 денежных единиц. Пример иллюстрирует масштабирование, а не реальную рыночную котировку.
Одного answer недостаточно. Важно проверить допустимость значения для выбранного показателя, время updatedAt и правила допустимого возраста. Порог свежести выбирается с учётом конкретного feed, его heartbeat, условий обновления и задачи приложения. Универсальное «всегда разрешать данные за последние 24 часа» может быть слишком широким или ошибочным правилом.
В некоторых L2 дополнительно требуется учитывать остановку sequencer и период после его восстановления. В таком состоянии время и доступность сети влияют на корректность бизнес-действия. Это отдельное условие, а не поправка к количеству десятичных знаков. Использование Chainlink Data Feeds, выбор feed.
Для первого упражнения лучше взять локальный источник с управляемыми ответами: свежий, устаревший, недопустимый и недоступный. Так ученик сможет объяснить отказ операции без зависимости от текущего рынка. Интеграция реального feed становится следующим этапом, где отдельно фиксируются поддерживаемая сеть и условия поставщика.
Асинхронные запросы: от Functions к CRE
Вызов внешнего вычисления часто состоит из двух операций: отправки запроса и последующего получения результата. Это не синхронная функция, которая мгновенно вернула JSON в тот же стек вызовов. Для каждого запроса сохраняем идентификатор, назначение, ожидаемый формат и состояние обработки.
В библиотеке запрос может определять статус внешней проверки выпуска. Ответ должен относиться именно к этому выпуску и запросу. Нельзя применить поздний ответ к новому курсу только потому, что на странице всё ещё открыт похожий виджет. Повторный ответ тоже не должен повторно выдавать доступ или изменять историю.
Состояния такого процесса удобно описать как created, requested, answered, failed и expired. Истечение времени ожидания в интерфейсе не доказывает, что ответ никогда не придёт. Контракт или сервер должен иметь явное правило для позднего ответа и для повторной попытки. Ошибка внешнего вычисления сохраняется отдельно от успешно полученного значения.
Старые видео могут использовать Chainlink Functions. По официальному сообщению этот сервис снят: mainnet 30 июня 2026 года, testnet 15 июня. Для новых маршрутов документация направляет к Chainlink Runtime Environment — CRE. Поэтому старые подписки и команды не выдаём за актуальную инструкцию нового проекта.
Chainlink Automation тоже снят: версии 1.x 30 июня 2026 года, 2.1 31 июля, testnet 24 июня. Исторический check/perform полезен для понимания повторной проверки условий, но новая программа изучает современный маршрут и собственные локальные модели. В любом варианте сохраняются назначение запроса, происхождение ответа, состояние и политика повторов.
Что меняется при переходе в L2
У L2 есть собственные сетевые параметры, RPC и адреса экземпляров. Низкая стоимость операции не делает её тем же вызовом, который уже отправлен в L1. Веб-приложению нужен явный выбор сети и политика подтверждений для конкретного назначения.
Нужно различать быстрое принятие операции оператором, публикацию связанных данных или результатов в L1 и окончательное завершение вывода. У optimistic и ZK-систем разные механизмы подтверждения и вывода; точные задержки и ограничения определяются конкретным протоколом. Нельзя заменить их одним обещанием «мост работает моментально».
Межсетевое сообщение также проходит несколько этапов. Для публикации курса из L1 в L2 нужно проверить источник сообщения, разрешённого отправителя и целевую сеть, сохранить идентификатор и исключить повторное применение. Даже если контракт доставки вызывает приёмник корректно, приёмник обязан проверить свою прикладную политику: не всякое доставленное сообщение разрешает изменить реестр.
В будущей лаборатории сначала смоделируем отправку и доставку локально. Интерфейс покажет отдельные состояния исходной операции и сообщения назначения. При недоступности второй сети первая отправка не объявляется исчезнувшей; сохраняются обе части истории. Только после такого упражнения имеет смысл переходить к конкретному мосту или CCIP с его актуальными настройками.
Переход в L2 требует исследовать возможность обновления протокола, полномочия операторов, доступность данных и маршрут выхода. Это помогает оценить зависимости приложения, а не только сравнить комиссии. Основные различия собраны в объяснении масштабирования Ethereum.
Как понимать ZK-доказательства
Доказательство вычисления показывает выполнение определённого отношения между входами, скрытыми данными и результатом в рамках выбранной системы. Проверяющая программа видит доказательство и публичные входы. Но она не подтверждает любое утверждение автора интерфейса: смысл зависит от того, что именно задано вычислением.
Например, можно исследовать подтверждение определённого свойства учебного документа без публикации всех исходных данных. Для этого нужно определить отношение, формат witness, публичные входы и способ получения проверяющего ключа. Также важно связать доказательство с нужным действием и адресатом, чтобы его нельзя было использовать как неограниченное повторяемое разрешение.
ZK-rollup и приватное приложение — разные понятия. Использование доказательства корректности исполнения не скрывает автоматически все данные пользователей, а скрытый witness не делает анонимными сетевые запросы. Эти свойства следует разбирать отдельно, без обещания приватности по одному названию технологии.
Собираем расширение библиотеки
Итоговая архитектура хранит учебные тексты и исходные копии вне контракта, публикует точный идентификатор выпуска, читает реестр через RPC и показывает состояние операций в браузере. Если появляются оракул, L2 или новый механизм имени, для каждого добавляются отдельные правила доверия, обновления и отказа.
Для следующего практического шага возьмём один выпуск и одну сеть. Подготовим файлы, точный манифест, воспроизводимый импорт и два независимых маршрута получения данных. Затем разберём недоступность хранения и несовпадение отпечатка. Лишь после этого расширим пример внешней проверкой и межсетевым сообщением. Такой порядок позволяет понять результат каждого шага, сохраняя общую задачу.
Все пять направлений, существующая лаборатория сертификатов и программа дальнейших уроков доступны в оглавлении Bitcoin, Solidity и Web3. Основания для работы с содержимым описаны в документации адресации IPFS и руководстве по pinning.