Четыре уровня, которые нельзя смешивать
УровеньВопросEvidence
DeploymentКакой код исполняется на этом blockchain ID, address, bytecode и proxy implementation
Role IDКакой bytes32 проверяетсяABI/source/constant или фактический calldata
Admin edgeКто может изменить рольgetRoleAdmin(targetRole)
MembershipЕсть ли право у address сейчасhasRole(role, account) на выбранном block
Четыре уровня, которые нельзя смешивать
Уровень
Deployment
Вопрос
Какой код исполняется на этом block
Evidence
chain ID, address, bytecode и proxy implementation
Уровень
Role ID
Вопрос
Какой bytes32 проверяется
Evidence
ABI/source/constant или фактический calldata
Уровень
Admin edge
Вопрос
Кто может изменить роль
Evidence
getRoleAdmin(targetRole)
Уровень
Membership
Вопрос
Есть ли право у address сейчас
Evidence
hasRole(role, account) на выбранном block

Роль принадлежит deployment на конкретной сети и блоке

Запишите chain ID, contract address, block number/hash и hash runtime bytecode. Если адрес — proxy, определите implementation, активную на этом блоке: вызов идёт в её код, но role state обычно остаётся в storage proxy. Текущий ABI новой implementation нельзя переносить назад без проверки. Для этого сначала нужен разбор proxy, upgrade и admin keys, а затем AccessControl-граф.

Имя роли сначала связывают с точным bytes32

В распространённой реализации role identifier получают как bytes32 constant, часто keccak256 от строки, но само UI-название не гарантирует этот способ или spelling. Возьмите значение из verified source, ABI-accessible getter, deployment artifacts либо декодированного вызова и запишите его полностью. DEFAULT_ADMIN_ROLE в OpenZeppelin AccessControl — отдельная роль со специальной чувствительностью, а не синоним owner любой системы.

Отчёт аудита полезен только если совпадают repository, commit, deployment и implementation. Finding о centralization или role setup не устанавливает текущий on-chain membership без state read; методика проверки scope и remediation остаётся отдельным шагом.

getRoleAdmin строит ребро управления, а не список людей

Для каждой чувствительной role вызовите getRoleAdmin(role). Затем повторите для полученной admin role и проверьте hasRole(adminRole, candidateAccount). В базовом AccessControl DEFAULT_ADMIN_ROLE по умолчанию администрирует и саму себя, поэтому её holder способен grant/revoke другие роли и добавлять новых default admins. Contract может изменить admin relation через внутреннюю настройку, поэтому предположение по названию недопустимо.

Decision tool для источников membership
НаблюдениеЧто доказываетГраница
hasRole=true на block NАдрес имеет эту role в snapshot NНе доказывает будущий state или право использовать каждую функцию
RoleGranted eventСобытие grant было записаноПоздний revoke или upgrade может изменить итог
RoleRevoked eventСобытие revoke было записаноНужен receipt success и новый hasRole=false
getRoleAdmin=XRole X управляет target roleНе показывает members X
AccessControlEnumerable interface/codeВ deployment может быть on-chain enumerationБазовый AccessControl её не предоставляет
Decision tool для источников membership
Наблюдение
hasRole=true на block N
Что доказывает
Адрес имеет эту role в snapshot N
Граница
Не доказывает будущий state или право использовать каждую функцию
Наблюдение
RoleGranted event
Что доказывает
Событие grant было записано
Граница
Поздний revoke или upgrade может изменить итог
Наблюдение
RoleRevoked event
Что доказывает
Событие revoke было записано
Граница
Нужен receipt success и новый hasRole=false
Наблюдение
getRoleAdmin=X
Что доказывает
Role X управляет target role
Граница
Не показывает members X
Наблюдение
AccessControlEnumerable interface/code
Что доказывает
В deployment может быть on-chain enumeration
Граница
Базовый AccessControl её не предоставляет

Полную историю RoleGranted, RoleRevoked и RoleAdminChanged собирают по адресу deployment, с genesis/deployment block до выбранного блока и без обрезанного диапазона RPC. Но итог всегда подтверждают eth_call к hasRole. Правила чтения событий и logs помогают обнаружить пропущенный диапазон, reorg marker или неверный emitter.

Revoke планируют от функции назад к recovery path

Preflight изменения прав

  1. 1
    Назовите capability

    Перечислите функции, защищённые целевой role, включая pause, mint, upgrade, config и emergency path.

  2. 2
    Зафиксируйте graph

    Для target role и всех admin roles сохраните bytes32, hasRole, getRoleAdmin, block и implementation.

  3. 3
    Найдите независимый путь

    Убедитесь, что после revoke остаётся проверенный multisig/timelock/admin, способный выполнить recovery без отзываемого аккаунта.

  4. 4
    Симулируйте exact call

    Проверьте from, to, calldata, chain, nonce и expected post-state. eth_call не гарантирует включение, но ловит часть ошибок.

  5. 5
    Исполните и подтвердите

    После successful receipt перечитайте hasRole и admin graph на новом confirmed block.

grantRole и revokeRole доступны только аккаунту, имеющему admin role целевой роли в стандартной реализации. renounceRole предназначен для отказа вызывающего аккаунта и в Contracts 5.x требует caller confirmation; он не является способом произвольно убрать чужого holder. AccessControlDefaultAdminRules, если deployment действительно его использует, добавляет одного default admin и двухшаговую задержанную передачу — эту модель нельзя приписывать обычному AccessControl.

Потерянный admin не восстанавливается универсальной транзакцией

Stop-сигналы

  • role ID вычислен из подписи в интерфейсе без сверки source или calldata;
  • membership выводят только из events либо из неполного диапазона logs;
  • proxy implementation и block context не закреплены;
  • предлагается revoke последнего действующего admin без отдельного recovery path;
  • eth_call или симуляцию называют гарантией успешного будущего включения;
  • для проверки публичного state просят seed, private key или blind signature.

Если ни один доступный account не имеет требуемую admin role, OpenZeppelin AccessControl не содержит скрытого off-chain override. Возможность восстановления должна следовать из другого реально существующего механизма deployment: proxy upgrade authority, timelock, модуль governance или custom emergency function. Перед подписью такого действия проверяйте фактические байты и адрес назначения, а не обещание оператора.

Источники

Мы используем прямые ссылки и фиксируем дату проверки. Полный текст чужих материалов не перепечатывается.

  1. OpenZeppelin Contracts 5.x — Access Control OpenZeppelin · Проверено 23 августа 2026 г. в 20:06 GMT+5
  2. OpenZeppelin Contracts 5.x API — Access OpenZeppelin · Проверено 23 августа 2026 г. в 20:06 GMT+5
  3. OpenZeppelin Upgrades — Proxy Pattern OpenZeppelin · Проверено 23 августа 2026 г. в 20:06 GMT+5
  4. Ethereum.org — JSON-RPC API ethereum.org · Проверено 23 августа 2026 г. в 20:06 GMT+5
Материал носит информационный характер и не является индивидуальной рекомендацией. Криптоактивы связаны с риском волатильности, технических сбоев, хищения и полной потери средств.