Solidity: проверка манифеста публикации
Все элементы готовы к соединению: есть реестр, стабильный номер курса, отпечаток файла и описание развёртывания. Теперь составим маршрут, по которому читатель получает материал и понимает, соответствует ли он объявленному выпуску. Этот маршрут не должен превращать один зелёный значок в обещание полной безопасности.
Рассмотрим курс 17. Его URL на сайте остаётся обычной страницей, а содержимое описывает внешний манифест. Контракт сообщает текущий hash и активность. Соединение этих сведений происходит в приложении; сам реестр не открывает HTTP-страницы.
Два документа с разными обязанностями
Запись развёртывания содержит сеть и адрес экземпляра. Манифест выпуска содержит сведения о материале. Не следует соединять их в один бесконтрольный файл, который одновременно выбирает доверенного издателя и предлагает содержимое: тогда читатель может получить самосогласованное объявление от произвольного источника.
{
"schema": 1,
"courseId": "17",
"releaseLabel": "Редакционный выпуск 1",
"title": "Статический сайт из Markdown",
"entry": "/courses/static-markdown/",
"licenseNotice": "Условия указаны на странице проекта"
}
Это пример содержимого файла, байты которого определены редакционным выпуском. Поле entry показывает обычный путь материала. Оно не становится автоматически неизменным: для проверки нужен связанный отпечаток всего выбранного артефакта и известное правило расчёта.
Номер хранится строкой, чтобы общий JSON-договор мог представлять большие целые значения без округления. Для номера 17 это не обязательно по диапазону, но единый способ помогает не менять формат позже. Проверка схемы должна отличать строку номера от произвольного названия.
Последовательность читателя
Сначала приложение выбирает известную сеть и экземпляр реестра. Затем читает courses(17) на определённом состоянии. Если active=false, оно показывает предупреждение, а не утверждает действительность выпуска. Если hash нулевой, публикации в этой модели нет. Только после этого полученный файл сравнивается с ненулевым ожидаемым значением.
1. Известные реквизиты: сеть + адрес + ABI
2. courses(17): ожидаемый hash и active
3. Получение конкретного файла
4. Расчёт SHA-256 от точных сохранённых байтов
5. Сравнение с ожидаемым hash
6. Разбор схемы и courseId манифеста
Порядок сравнения и разбора можно организовать технически по-разному, но смысл сохраняется. Проверяется определённый артефакт, а не произвольно переформатированный объект. Если сначала разобрать JSON и заново сериализовать его, отпечаток уже относится к другим байтам, если только договор прямо не выбрал канонизацию.
Схема манифеста важна после целостности. Честно объявленный hash может относиться к файлу с неизвестной формой. Поэтому совпадение байтов не означает, что приложение обязано исполнять любое предложенное содержимое. Нужно ограничить допустимые поля, типы и переходы.
Ссылка не должна стать исполнением
Если манифест содержит entry, сайт интерпретирует его по своим правилам. Не нужно превращать поле в произвольный код или HTML без обработки. Даже доверенная редакция может ошибиться, а механизм целостности не заменяет безопасное отображение данных.
Для относительного пути можно определить разрешённые начала маршрута и исключить неожиданные схемы. Если допускаются внешние ссылки, интерфейс должен ясно показывать переход на другой источник. Это обычное проектирование веб-приложения, которое остаётся необходимым при наличии блокчейна.
Личные данные читателя в манифест не входят. Выпуск должен быть публичным учебным документом. Покупки, почта и серверные сессии имеют отдельные договоры хранения. Добавление их в публичный файл с последующим хешированием не создаёт конфиденциальности.
Четыре возможных результата
Вместо одного булевого «проверено» полезно сохранять несколько наблюдений. Источник реестра известен или нет. Запись активна или нет. Файл доставлен или нет. Отпечаток совпал или нет. Эти состояния помогают человеку понять следующий шаг.
| Наблюдение | Сообщение |
|---|---|
| Невозможно прочитать реестр | Не удалось получить актуальные сведения |
| Выпуск отключён | Редакция не считает этот выпуск активным |
| Файл недоступен | Запись известна, получение содержимого не удалось |
| Hash отличается | Полученные байты не совпали с объявленным выпуском |
| Hash совпал | Целостность выбранного артефакта подтверждается сравнением |
Если новый выпуск появился между чтением реестра и загрузкой файла, интерфейс может повторить чтение и объяснить смену hash. Не нужно сразу обвинять источник в повреждении. Однако автоматическое повторение должно иметь предел, чтобы постоянно меняющаяся запись не создавала бесконечную загрузку.
История и устойчивые ссылки
Обычный текущий URL может вести на новый выпуск. Для архивной цитаты лучше сохранять реквизиты определённого файла и исторического объявления. В CourseCatalogV2 такую связь можно дополнить номером revision, но базовый реестр требует истории событий или отдельной редакционной записи.
Сам URL страницы курса остаётся полезным для навигации и SEO. Не требуется менять прежние адреса сайта только потому, что появился отпечаток. Web3-модель добавляет проверяемую связь с выпуском, а не заставляет перенести весь сайт в транзакции. Это соответствует опыту ProfessorWeb: стабильные пути и обновляемый контент могут сосуществовать.
В результате читатель получает честное объяснение: какой реестр прочитан, какой выпуск ожидается и что произошло при сравнении. Такие реквизиты можно сохранить как отчёт без секретов и без выдуманной финальности. Следующая страница соберёт исходный контракт целиком и покажет завершённую карту допустимых действий. ABI Solidity и принципы безопасности помогают удержать границы данных и исполнения.
Отчёт без лишних обещаний
Можно сохранить небольшой результат чтения: сеть, адрес, courseId, ожидаемый hash, алгоритм SHA-256, полученный hash и статус активности. Добавьте сведения о моменте наблюдения и инструменте. Этот документ объясняет, что сравнивалось, но не является универсальным сертификатом качества учебника.
Если файл не получен, поле полученного hash остаётся пустым. Если реестр недоступен, отсутствует актуальное ожидание. Не нужно заполнять такие поля прежними значениями без обозначения кэша. Иначе отчёт выглядит полным, хотя его части относятся к разным наблюдениям.
Особенно важно разделить проверку файла и вход пользователя. Для скачивания публичного выпуска не нужна подпись кошелька. Добавление обязательной подписи в этот маршрут изменяет пользовательский опыт и может создать лишнее разрешение. Кошелёк применяется к отдельным действиям, для которых его роль действительно нужна.
В упражнении поменяйте только URL доставки, сохранив точные байты файла. Отпечаток должен соответствовать прежнему выпуску. Теперь поменяйте только байты при прежнем URL: сравнение меняется. Это наглядно отделяет адрес получения от идентификатора содержимого, на котором построен договор реестра.
Оглавление курса. Листинги, расчёты и наблюдения здесь разобраны как ожидаемое поведение; компиляция, учебные программы и проверки при написании не запускались.