Локальная EVM и адрес развёрнутого контракта
Оглавление серии «Реестр» · Урок 5 из 10.
Контракт выдачи и отзыва определён. Теперь разберём самостоятельную локальную лабораторию, в которой его можно разместить. Используем Anvil из Foundry 1.3.1, цепочку с идентификатором 31337 и RPC только на loopback. Ожидаемый результат после действий читателя — адрес конкретного экземпляра контракта и конфигурация веб-страницы, содержащая этот адрес и начальный блок. При подготовке курса эти действия не выполнялись: здесь нет готового развернутого адреса, выдуманного хеша транзакции или отчёта компиляции.
Исходник и развёрнутый экземпляр — разные сущности. Один файл Solidity можно разместить несколько раз, получив несколько адресов с независимым хранилищем. Даже одинаковый байткод не делает записи общими. Браузеру необходима конкретная пара сеть-адрес. Имя CertificateRegistry подходит инструменту компиляции, но не сообщает RPC, к какому состоянию нужно обратиться. Поэтому конфигурация приложения станет отдельным файлом, который читатель заполняет результатом собственной лаборатории.
Инструменты и закреплённый профиль
Foundry включает Forge для подготовки контрактов и Anvil для локального узла. В серии выбрана версия 1.3.1, а компилятор Solidity закреплён как 0.8.30. Официальная инструкция установки позволяет подготовить инструменты на компьютере читателя. Не нужно вставлять случайную команду загрузки из неизвестного источника или смешивать настройки разных выпусков. После установки полезно самостоятельно посмотреть версии и убедиться, что используются выбранные инструменты, а не другая ранее установленная копия.
Наш foundry.toml задаёт evm_version = "cancun". Локальный узел запускается с соответствующим hardfork. Так код компилятора и среда исполнения относятся к одному профилю возможностей. Если изменить компилятор или целевую EVM, требуется пересмотреть лабораторию, а не считать прежний набор команд автоматически подходящим. Особенно важно не выдавать ошибку неподдерживаемой инструкции за ошибку функции сертификата: причина может лежать до начала предметной логики.
Локальный RPC
Читатель запускает узел в отдельном терминале. Привязка к 127.0.0.1 означает доступ на собственном компьютере. В этом курсе не открываем локальные разблокированные аккаунты наружу и не публикуем RPC в интернете. Порт 8545 относится к отдельному учебному серверу, а порт Vite — к веб-странице. Это разные процессы, у которых разное назначение. Наличие работающей страницы не доказывает наличие доступной EVM, и наоборот.
anvil --host 127.0.0.1 --chain-id 31337 --hardfork cancun
Anvil создаёт учебные аккаунты и локальные средства. Они не являются настоящими деньгами. Для действий используйте отдельную лабораторию и значения её вывода. Не переносите показанные служебные ключи в настоящую сеть. В наших исходниках ключей нет: способ развёртывания обращается к локальному разблокированному адресу через RPC. Это специально ограниченный метод для узла под контролем читателя, а не пример управления ключами производственной организации.
Создание конкретного экземпляра
В корне выбранного состояния Forge получает путь и имя контракта. Отправителем станет выбранный локальный аккаунт, который конструктор сохранит владельцем. В следующей команде ЛОКАЛЬНЫЙ_АДРЕС — заполнение, которое необходимо заменить адресом собственной лаборатории. Она не готова к запуску до этой замены. Команда приведена для самостоятельной работы и не выполняется при написании курса. Используется --broadcast, чтобы обозначить отправку, а не только подготовку операции.
forge create src/CertificateRegistry.sol:CertificateRegistry \
--rpc-url http://127.0.0.1:8545 \
--unlocked --from ЛОКАЛЬНЫЙ_АДРЕС --broadcast
Forge может получить закреплённый компилятор при собственной подготовке. Полученный артефакт относится к исходнику и параметрам этого шага. Не следует одновременно редактировать контракт и продолжать использовать старый адрес, ожидая появления новых функций в старом экземпляре. Изменение файла не обновляет уже развёрнутый код. Для этой лаборатории после изменения исходника создают новый экземпляр и отдельно обновляют конфигурацию веб-страницы. Сложные схемы обновления контрактов здесь не используются.
Конфигурация веб-страницы
В архиве файл web/public/deployment.json намеренно содержит нулевой адрес. Это явное незавершённое состояние, а не адрес демонстрационного сервиса. Читатель заменяет его полученным адресом и записывает блок развёртывания. Строковое представление блока удобно для JSON и дальнейшего преобразования в BigInt. Поле chainId остаётся числом 31337. В следующих уроках браузер будет проверять эти сведения перед чтением и отправкой операции.
{
"chainId": 31337,
"address": "0x0000000000000000000000000000000000000000",
"startBlock": "0"
}
Начальный блок нужен для ограниченного поиска событий. Если поставить слишком поздний блок, история выдач может оказаться неполной. Если без необходимости начинать с нуля огромной настоящей цепочки, запрос станет неоправданно дорогим и может быть отклонён RPC. В небольшой свежей лаборатории блок ноль допустим, но для конкретного экземпляра полезно записать фактическую границу развёртывания. Это часть связи приложения с артефактом, а не декоративное описание в README.
После перезапуска узла
Состояние обычного нового Anvil не обязано сохранять прошлую лабораторию. После перезапуска контракт по старому адресу может отсутствовать, даже если браузер сохранил deployment.json. Иногда детерминированная последовательность действий создаёт похожие адреса, но на это нельзя опираться как на гарантию прежних данных. Проверяем текущую сеть и наличие кода. Если нужен перенос состояния локального узла, проектируйте его отдельно и документируйте способ сохранения; в нашей серии это не скрытая автоматическая возможность.
Наличие кода по адресу тоже не доказывает, что это нужная версия реестра. В дальнейшей лаборатории читатель сам контролирует исходник и развёртывание. Для настоящего приложения потребуется более строгая связь с выбранным байткодом, релизом и доверенной сетью. Наш браузерный guard отсеет нулевой адрес, другую сеть и отсутствие кода, но не заявит проведение аудита контракта. Границы каждой проверки следует понимать до того, как показать пользователю уверенную подпись о найденном документе.
Самостоятельное наблюдение среды
После собственных действий читатель должен получить ненулевой адрес и сохранить конфигурацию рядом с веб-ресурсами. Затем можно остановить узел и увидеть, что сетевой запрос к RPC невозможен, хотя HTML-страница остаётся доступной. Это полезное разделение готовности среды и готовности интерфейса. Пока в данном состоянии браузер рассчитывает хеш, но ещё не читает контракт. Подключение viem в следующем уроке создаст понятный путь от конфигурации к конкретному getter.
Команда создания описана в Forge create, локальный сервер — в документации Anvil, выбранный выпуск — в Foundry 1.3.1. Сохраняем адрес, сеть и блок как договорённость лаборатории. Эти значения нельзя выводить из красивого названия приложения или подставлять из случайного примера: они должны относиться к экземпляру, который читатель действительно создал на собственном компьютере.
Исходники этого шага
Архив серии содержит полную папку lesson-05. Возьмите именно её; переносить файлы из соседних папок не требуется. Версии и самостоятельная подготовка описаны в README. Пример, установка зависимостей и его выполнение при написании не запускались; результаты в тексте ожидаются по разбору исходников. Материал сохранён локально как Markdown-черновик.