Перейти к содержанию

Constructor и immutable в Solidity: настройка издателя

Теперь реестр имеет форму данных, но ещё не определено, кто может их менять. Базовый пример выбирает одного издателя на весь срок жизни обычного экземпляра. Адрес назначается конструктором и сохраняется как immutable. Это простая модель с ясными преимуществами и существенным ограничением восстановления.

В этом уроке рассмотрим создание экземпляра как отдельный этап. Конструктор не является методом, который читатель затем регулярно вызывает на сайте. Его параметры относятся к выпуску конкретного контракта, поэтому входят в запись развёртывания вместе с сетью и адресом.

Значение приходит при создании

Фрагмент из CourseCatalog:

error Unauthorized();
address public immutable publisher;

constructor(address publisher_) {
    if (publisher_ == address(0)) revert Unauthorized();
    publisher = publisher_;
}

Параметр publisher_ отдельно назван, чтобы отличать входное значение от поля экземпляра. Сначала проверяется ненулевой адрес. Затем сохраняется именно этот адрес. Программа не предполагает, что разворачивающий аккаунт обязательно должен стать издателем.

Представим, что технический аккаунт D размещает контракт и передаёт в конструктор адрес редакции P. После успешного создания getter publisher() должен возвращать P, а не D. Так можно разделить техническую работу выпуска и последующее управление публикациями. Если бы мы без объяснения записали publisher = msg.sender, модель стала бы другой.

Для учебного экземпляра адрес может относиться к локальному аккаунту. Для реальной редакции адрес может принадлежать отдельному контракту управления. Базовая проверка не требует, чтобы издатель всегда был внешним аккаунтом. Но другой контракт должен действительно уметь выполнить нужный вызов: красивый адрес в документе не создаёт такую способность.

Что означает immutable

immutable позволяет определить значение при создании и затем не менять его обычными присваиваниями в методах этого контракта. Это не универсальный механизм управления ролями. В исходном файле нет transferPublisher, аварийного назначения или отмены через сервер ProfessorWeb.

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

Также нельзя обещать читателю, что неизменяемый издатель означает неизменяемое содержимое. Издатель имеет право заменить текущий отпечаток через publish. Постоянство адреса и постоянство записи — разные свойства. Наш реестр сохраняет первого участника, но допускает развитие курса.

Ошибка в первоначальном адресе

Пусть технический аккаунт ошибся на один символ и передал другой ненулевой адрес. Проверка на ноль такую ошибку не обнаружит. Она проверяет только один недопустимый случай. Для предотвращения ошибочного назначения нужны процедура подготовки реквизитов и независимое подтверждение адреса до создания экземпляра.

Особенно важно не использовать сокращённый вид адреса для окончательного назначения. Строка 0x123…456 подходит компактной подписи, но скрывает большую часть значения. Подтверждение должно опираться на полную строку и понятный источник. Переключение сети также относится к процедуре: один и тот же набор байтов не доказывает ожидаемого участника в любой сети.

После создания читатель может проверить publisher() и сравнить с ожидаемым значением. Если оно отличается, нельзя продолжить публикацию и рассчитывать, что ошибка исправится сама. У нашего обычного экземпляра такого исправления нет. Возможный следующий выпуск — новый адрес с правильным конструктором и явная миграция выбора на сайте.

Вход конструктора Ожидаемое поведение Что остаётся проверить
Нулевой адрес Создание отклонено Правильный адрес издателя
Правильный P Экземпляр содержит P Сеть, артефакты, код
Другой ненулевой R Экземпляр содержит R Ошибка процедуры, не синтаксиса

Конструктор и начальное состояние

В нашей модели конструктор не публикует курс 17. После создания все записи mapping имеют стандартные значения. Это позволяет отдельно изучить запуск реестра и первое объявление курса. Иначе ошибка публикации могла бы смешаться с ошибкой параметров создания.

Некоторые приложения действительно инициализируют набор записей сразу. Тогда конструктор становится сложнее и может зависеть от числа элементов. Для нас это не нужно: одиночная публикация остаётся ограниченной операцией после создания. Адрес издателя — единственная предметная настройка начального экземпляра.

Важно также отличать конструктор обычного контракта от инициализатора модели с прокси. Конструктор реализации не записывает автоматически значения в хранилище прокси. В курсе прав мы введём такую систему отдельно, с другим состоянием и жизненным циклом. Нельзя заменить способ размещения исходного реестра и считать, что immutable publisher превратился в обычное настраиваемое поле прокси.

Документирование ограничения

Для сайта полезно сохранить не только publisherAddress, но и смысл права: «издатель выбран при создании и не передаётся средствами реестра». Человек должен понимать, что новая редакционная политика потребует отдельной модели. Иначе интерфейс может обещать возможность смены администратора, которой контракт не имеет.

Закреплённый издатель удобен для первого курса и независимых проверок: после любого набора допустимых публикаций его значение должно оставаться прежним. Но проверка этого свойства не доказывает безопасность управления ключами. Она проверяет конкретное правило кода. Такой уровень точности понадобится дальнейшему курсу Foundry.

Результат урока — ясный начальный этап: конструктор получает выбранный ненулевой адрес, экземпляр сохраняет его, текущие курсы пока пусты. Следующим шагом рассмотрим msg.sender, который позволяет сопоставить адрес вызова с этим первоначальным значением. Конструкторы и immutable описаны в руководстве языка.

Первоначальное право и процедура приёмки

Перед созданием экземпляра редакция может попросить будущий субъект подтвердить полный адрес через известный канал. Такое подтверждение является процедурой организации, а не магическим свойством конструктора. Конструктор проверит только объявленные условия. Если процедура пропущена, код не узнает об ошибке человека в ненулевом адресе.

После результата сверяют publisher и реквизиты экземпляра. Если контракт управления должен стать издателем, полезно заранее убедиться, что у него существует разрешённый маршрут к вызову publish. Проверка формы адреса сама по себе не доказывает работоспособность этого маршрута.

Не следует создавать восстановительную функцию «на всякий случай» без отдельной модели полномочий. Она изменила бы главное свойство исходного реестра: издатель перестал бы быть постоянным. Права аварийного администратора могут оказаться более сильными, чем обычные публикации. Такие возможности требуют собственного объяснения и курса управления.

В простом проекте выходом при ошибочном назначении является другой экземпляр и объявленный переход на сайте. История старого остаётся отдельно доступной. Это менее удобно, чем скрытая кнопка исправления, зато соответствует выбранному коду. Полезно назвать ограничение заранее, пока у модели нет реальных обязательств и пользовательских данных.

Оглавление курса. Листинги, расчёты и наблюдения здесь разобраны как ожидаемое поведение; компиляция, учебные программы и проверки при написании не запускались.

Оглавление серии