Первый проект Solidity: версия компилятора и профиль
Один и тот же исходный текст ещё не является полной спецификацией исполняемого контракта. На результат влияют версия компилятора, целевая EVM, оптимизация, библиотеки и аргументы конструктора. Прежде чем продолжить реестр курсов, зафиксируем эти параметры как часть учебного проекта.
Наш основной профиль — Solidity 0.8.30, EVM Cancun и Foundry 1.3.1. Это закреплённые версии лаборатории, согласованные с уже существующим примером ProfessorWeb. Мы не называем их последними и не выбираем автоматически для будущего публичного выпуска. Пока все действия остаются описанием: инструменты не устанавливаются и компиляция не запускается.
Что задаёт pragma
В начале файла укажем точную версию языка:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
Директива pragma ограничивает совместимость исходника с компилятором. Она не скачивает нужную программу и не определяет сеть развёртывания. Если выбранный компилятор не подходит, обработка такого файла должна остановиться. Поэтому сохранение директивы полезно, но не заменяет настройки инструмента сборки.
Запись с диапазоном, например ^0.8.30, имеет другой смысл: она допускает совместимые по указанному правилу версии. Для учебного сравнения нам важнее один известный профиль. Если автор прочитал предупреждение в новой версии и изменил настройку, это должно стать явным обновлением примера, а не незаметным побочным результатом установки зависимостей.
Идентификатор SPDX сообщает заявленную лицензию исходника. Он не доказывает, что автор имеет право перепубликовать чужой код. Наши короткие листинги создаются для учебной библиотеки; импортируемые библиотеки сохраняют собственные условия. По той же причине название файла или присутствие комментария «проверено» не является доказательством аудита.
Компилятор и целевая машина
Solidity переводит исходник в представление, которое затем исполняет EVM. Выбор целевой версии EVM ограничивает инструкции и правила, на которые может рассчитывать результат. Версия языка и версия EVM связаны, но не являются одним значением. Особенно это важно при работе с локальными цепочками или другими совместимыми сетями, где поддержка обновлений может отличаться.
Создадим содержимое учебного foundry.toml:
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.30"
evm_version = "cancun"
optimizer = false
Это файл конфигурации, а не отчёт о выполненной сборке. Здесь явно заданы расположение исходников, выходных данных и библиотек. Отключённая оптимизация выбрана для первого разбора, чтобы параметры не оставались неявными. Такой выбор не следует переносить в публичный выпуск без отдельного сравнения размера, стоимости и поведения.
Изменение оптимизации не должно менять задуманную бизнес-семантику. Однако полученный байткод, размер и затраты могут отличаться. Если два человека сравнивают хеш исполняемого кода, они обязаны сначала сверить эти настройки. Иначе различие хешей нельзя уверенно объяснить изменением одной строки исходника.
В будущем мы сохраним вместе с результатом версии инструментов и точные параметры. Установка «любой Foundry из основного канала» даст менее определённое окружение. Это особенно заметно в командах, где несколько редакторов повторяют лабораторию спустя месяцы. Выбранный профиль делает расхождение обсуждаемым, но не превращает старую зависимость в бессрочно безопасную.
Исходники и импорт
Сначала CourseCatalog обходится без внешних библиотек. Полный файл можно читать целиком: поля, конструктор, проверка издателя и две операции. Позже курс прав использует OpenZeppelin Contracts 5.4.0. Это отдельная закреплённая зависимость; её нельзя разрешать как произвольную будущую 5.x, если требуется повторяемость конкретного листинга.
Для проекта полезно различать три источника изменений. Первый — наш код. Второй — код библиотек. Третий — настройки и версия компилятора. Обновив библиотеку, следует рассмотреть её журнал изменений, требования языка и затронутые методы. При новой компиляции исходники библиотеки также относятся к проверяемому набору проекта.
Не стоит хранить в качестве единственного доказательства файл из временной вкладки Remix. Для курса нужен обычный исходник под управлением версий и записанные параметры. Браузерный инструмент удобен для ручного изучения, но сохранение состояния интерфейса не заменяет сохранение проекта.
| Изменение | Что требуется заново объяснить |
|---|---|
| Другой компилятор | Предупреждения, совместимость, известные ошибки |
| Другая EVM | Поддержку выбранных инструкций сетью |
| Другой оптимизатор | Байткод и параметры воспроизведения |
| Другая библиотека | Конструкторы, интерфейсы и изменения поведения |
| Другой издатель | Аргументы конструктора и полномочия экземпляра |
Профиль как документ
Сохраним простую запись проекта, которую можно прочитать без запуска:
{
"contract": "CourseCatalog",
"compiler": "0.8.30",
"evm": "cancun",
"optimizer": false,
"foundry": "1.3.1",
"exampleExecution": "not_run"
}
Значение not_run важно отделяет подготовку файла от полученного артефакта. В этой записи пока нет адреса контракта, блока развёртывания или хеша байткода, поскольку соответствующие действия не выполнялись. Заполнять их вымышленными значениями ради красивой таблицы нельзя.
Когда читатель самостоятельно подготовит окружение, он сможет сопоставить установленную программу с указанным профилем. Полученные предупреждения следует читать, а не скрывать, чтобы урок выглядел успешным. Также стоит обращаться к списку известных ошибок компилятора и оценивать применимость к конкретному коду и параметрам. Наличие фиксированной версии помогает воспроизвести пример, но не освобождает от такой оценки перед реальным выпуском.
Результатом урока становится набор входных условий сборки. Он ещё не доказывает, что контракт компилируется, и не содержит утверждения о выполненной проверке. Зато последующие страницы могут одинаково трактовать слово «наш исходник»: это текст CourseCatalog.sol вместе с версией Solidity, целевой машиной и явно выбранными настройками. Установка и выбор компилятора, конфигурация Foundry помогают уточнить эти входы.
При обновлении профиля
Переход к другой версии компилятора оформляется как изменение входов проекта. Сначала сохраняют прежний профиль, затем перечисляют новое значение и причины перехода. Ожидаемая бизнес-семантика остаётся предметом самостоятельного сравнения. Нельзя объявить совместимость только потому, что оба номера начинаются с 0.8.
Список известных ошибок тоже следует сопоставлять с используемыми конструкциями. Если в нашем исходнике нет соответствующего механизма, запись о проблеме не обязательно означает уязвимость именно реестра. Но отсутствие найденной записи также не является доказательством отсутствия всех проблем. Такой разбор требует точных параметров, которые мы только что зафиксировали.
Хороший редакционный комплект включает текстовую заметку о том, что именно поменялось: например, оптимизация включена для нового самостоятельного сравнения, а старые численные оценки больше не используются. Так читатель понимает границу версий, вместо того чтобы получать одну страницу с перемешанными условиями нескольких выпусков.
Оглавление курса. Листинги, расчёты и наблюдения здесь разобраны как ожидаемое поведение; компиляция, учебные программы и проверки при написании не запускались.