Solidity: отзыв роли и самостоятельный отказ
Редактор сменил команду, потерял устройство или больше не должен публиковать материал. Нужно убрать контрактное полномочие, а не только удалить имя из серверной таблицы. В AccessControl для этого есть revokeRole и renounceRole. Они похожи по результату, но имеют разные разрешённые субъекты.
Разберём их на издателе P и его администраторе A. Будем использовать отдельный EditorialCatalog либо EditorialRoster из предыдущих страниц. Роль PUBLISHER_ROLE по-прежнему означает возможность вызвать публикацию в выбранной модели, а не право на любой другой реестр.
Отзыв администратором
Внешний revokeRole(role,account) проверяет, что отправитель обладает текущей административной ролью указанного полномочия. A может убрать PUBLISHER_ROLE у P, если граф позволяет это. После успешного действия hasRole возвращает false, и последующий publish от P не проходит модификатор.
До: hasRole(PUBLISHER_ROLE,P)=true
A → revokeRole(PUBLISHER_ROLE,P)
После: hasRole(PUBLISHER_ROLE,P)=false
P → publish(17,H2): отказ по роли
Сохранённый H1 не удаляется из курса. Отзыв права влияет на будущие действия, а не переписывает прошлую публикацию. Если материал также нужно отключить, субъект с REVOKER_ROLE выполняет самостоятельный deactivate. Эти действия могут иметь разные адреса и разные причины.
Повторный revoke для уже отсутствующей роли не создаёт нового изменения состава. В закреплённой библиотеке событие отзыва связано с реальным удалением имеющегося полномочия. Однако административная проверка внешнего метода всё равно относится к вызывающему участнику. Нельзя считать повтор без прав универсально разрешённой операцией.
Отказ самого участника
renounceRole(role,callerConfirmation) предназначен для участника, который отказывается от собственного права. Второй аргумент должен соответствовать отправителю по правилам библиотеки. Это подтверждение, а не адрес произвольного коллеги, у которого пользователь хочет удалить роль.
P → renounceRole(PUBLISHER_ROLE,P): собственный отказ
R → renounceRole(PUBLISHER_ROLE,P): неверное подтверждение
Роль может отсутствовать у отправителя, но это не даёт ему власти над чужим адресом. Форма подтверждения помогает исключить ошибочную передачу другого account в пользовательском интерфейсе. Панель должна ясно показывать, что речь о собственной роли, а не об административном отзыве.
После отказа P не способен сам вернуть роль, если отдельно не имеет её административного права. Возвращение выполняет соответствующий администратор. Поэтому renounce не является временным выключателем, который обязательно можно включить обратно из той же формы.
Скомпрометированный субъект
Если ключ P доступен постороннему, публикация может продолжаться до успешного отзыва и включения изменения в принятую историю. Удаление P из формы сайта не ограничивает другой клиент. Это практическая причина хранить карту административного субъекта и процедуру реагирования заранее.
Сам отказ через скомпрометированный ключ также не даёт гарантии спокойного порядка. Другой участник может пытаться выполнить действие до отзыва. Поэтому систему нельзя считать защищённой только от наличия кнопки renounce. Требуются подтверждённый результат и проверка последующей истории публикаций.
Если у P несколько ролей, удаление одной не убирает остальные. Publisher может одновременно иметь административное право и снова назначить себе публикацию. Разбор инцидента должен учитывать все прямые и косвенные маршруты, а не единственный hasRole для знакомого имени.
Последний администратор
В простом AccessControl DEFAULT_ADMIN_ROLE управляет самим собой. Отзыв или отказ последнего доступного участника способен оставить систему без маршрута назначения ролей. Это не автоматическая передача всем членам редакции и не создание нового владельца.
Перед добровольным отказом полезно проверить, кто сможет поддерживать граф после него. Для отдельных ролей можно назначить нового управляющего субъекта заранее. Для главной роли существует более строгий механизм, который изучим в следующем уроке. Его нельзя считать уже включённым в обычный AccessControl.
| Операция | Разрешённый субъект | Чьё право меняется |
|---|---|---|
| revokeRole | Администратор указанной роли | Заданный account |
| renounceRole | Подтверждающий своё отправление участник | Его собственное |
| Серверное удаление сотрудника | Администратор сайта | Само по себе не меняет контракт |
Интерфейс после изменения
Панель читает актуальные hasRole и getRoleAdmin. Если чтение не удалось, нельзя показывать «право отозвано» только потому, что запрос завершился ошибкой. Если действие ещё ожидает, сохраняется промежуточное состояние намерения, которое не выдаётся за результат.
Для неизвестной квитанции сначала восстанавливают известное действие, затем читают право. Текущий false объясняет состояние, но не всегда связывает его с конкретной попыткой: другой администратор мог выполнить отзыв. История RoleRevoked помогает установить последовательность.
Полезно отделить операторское сообщение от публичного интерфейса читателя. Читатель видит текущий выпуск и его статус. Редакционная панель показывает роли, адреса и административные действия. Нельзя раскрывать секреты кошельков в отчёте ради подробности; публичных реквизитов и известных событий достаточно для модели.
Упражнение со старой формой
P открыл publish-форму, когда имел роль. A успешно отозвал её до исполнения. Теперь запрос P отклоняется, даже если кнопка оставалась активной в устаревшей вкладке. Контракт оценивает текущее право, а не серверный скриншот момента открытия.
Затем A возвращает роль, и P может выполнить новый допустимый вызов. Прежний отказ не становится успешной транзакцией задним числом. Такое рассуждение удерживает временную последовательность и не смешивает изменённое право с результатами старых действий.
Мы получили два разных маршрута удаления полномочия и поняли их ограничения. Исходник AccessControl 5.4.0 позволяет сверить callerConfirmation, административную проверку и события.
Отзыв и токены доступа
Удаление издательской роли не меняет баланс учебных токенов P, если такая независимая система существует. Также владение абонементом не возвращает административную роль. Это разные контракты и разные свойства, которые нельзя объединять словом «доступ» без уточнения.
Для редакционного отчёта перечислите, какие именно полномочия отозваны и какие остаются. Участник может сохранить REVOKER_ROLE после удаления PUBLISHER_ROLE. Если случай связан с потерей устройства, такая остаточная власть может быть нежелательна. Решение зависит от модели инцидента, а не от обычного названия роли.
При самостоятельном упражнении отдайте P одновременно Publisher и EditorAdmin, затем удалите только Publisher. P способен назначить это право снова. Такой результат показывает, почему успешный revoke не всегда означает окончательное ограничение субъекта. Косвенные маршруты из предыдущего графа должны входить в тот же анализ.
Для самостоятельного уточнения: AccessControl.sol (5.4.0).
Оглавление курса. Листинги, расчёты и наблюдения здесь разобраны как ожидаемое поведение; компиляция, учебные программы и проверки при написании не запускались.