SymbioticISM.sol
Обзор
Контракт SymbioticISM реализует межцепочечный модуль безопасности (Interchain Security Module, ISM), обеспечивающий проверку сообщений в инфраструктуре Hyperlane с помощью сети валидаторов Symbiotic. Основная задача контракта — гарантировать подлинность и целостность межцепочечных сообщений, опираясь на кворум валидаторов, которые подписывают и подтверждают корректность сообщений.
Контракт поддерживает управление ролями, возможность приостановки работы (pausing), а также аварийное управление. Он взаимодействует с системой валидаторов, хранит статус проверок сообщений и обеспечивает проверку подписей валидаторов.
Структуры и основные компоненты
Роли доступа
VALIDATOR_ROLE— роль валидатора, который подтверждает сообщения.PAUSER_ROLE— роль, позволяющая приостанавливать и возобновлять работу контракта.EMERGENCY_ROLE— роль для экстренных операций, например, принудительной верификации сообщения.DEFAULT_ADMIN_ROLE— администратор, управляющий ролями и настройками.
Константы
VERIFICATION_TIMEOUT— тайм-аут проверки сообщения (3600 секунд, 1 час).MAX_VALIDATORS_PER_VERIFICATION— максимальное количество валидаторов (100).quorumThreshold— порог кворума в базисных пунктах (6700 = 67%).
Перечисление
enum VerificationStatus {
PENDING, // Ожидает проверки
VERIFIED, // Проверено успешно
FAILED, // Проверка провалена
EXPIRED // Время проверки истекло
}
Структуры данных
MessageVerification
Хранит информацию о статусе проверки сообщения:
messageId— идентификатор сообщения (хеш).originиdestination— домены отправителя и получателя.senderиrecipient— адреса отправителя и получателя.bodyHash— хеш тела сообщения.timestamp— время запроса проверки.status— текущий статус проверки.validatorCount— количество валидаторов, подтвердивших сообщение.validatorSigned— маппинг валидаторов, которые уже подписали.
ValidatorVerification
Информация о проверке одного валидатора:
validator— адрес валидатора.signature— подпись валидатора.timestamp— время проверки.isValid— валидность подписи.
HyperlaneMessage
Представление сообщения Hyperlane для запроса проверки:
messageId,origin,destination,sender,recipient— идентификаторы и адреса.body— тело сообщения.metadata— метаданные сообщения.
Функции и методы
Конструктор
constructor(address _admin)
Инициализирует контракт, назначая адрес администратором и выдавая ему основные роли (DEFAULT_ADMIN_ROLE, PAUSER_ROLE, EMERGENCY_ROLE). Проверяет, что _admin не равен нулевому адресу.
Проверка сообщения (view)
function verify(bytes calldata metadata, bytes calldata message) external view returns (bool verified)
Проверяет, был ли ранее верифицирован переданный message. Для этого:
Вычисляет
messageId— хеш сообщения.Возвращает
true, если статус сообщения —VERIFIED.Иначе —
false.
Запрос проверки сообщения
function requestVerification(HyperlaneMessage calldata message) external whenNotPaused returns (bytes32 messageId)
Инициирует процесс верификации сообщения:
Проверяет валидность
messageIdи поддерживаемость доменов.Если проверка для сообщения уже существует — возвращает её.
Иначе создаёт новую запись в
verifications.Устанавливает статус в
PENDING.Эмитит событие
MessageVerificationRequested.
Верификация сообщения валидатором
function verifyMessage(bytes32 messageId, bytes calldata signature) external onlyRole(VALIDATOR_ROLE) whenNotPaused
Валидатор подтверждает сообщение:
Проверяет существование и статус проверки.
Проверяет тайм-аут проверки.
Проверяет, что валидатор ещё не подписывал.
Проверяет подпись валидатора методом
_verifyValidatorSignature.Обновляет счётчик валидаторов.
Если превышен порог кворума — статус меняется на
VERIFIED.Эмитит события
ValidatorVerifiedиMessageVerified(если кворум достигнут).
Получение статуса проверки сообщения
function getVerificationStatus(bytes32 messageId) external view returns (VerificationStatus status, uint256 validatorCount, uint256 requiredValidators)
Возвращает текущий статус проверки, количество подписавших валидаторов и необходимое число для кворума.
Проверка, подтверждено ли сообщение
function isMessageVerified(bytes32 messageId) external view returns (bool verified)
Возвращает true, если сообщение проверено.
Получение информации о проверке конкретным валидатором
function getValidatorVerification(bytes32 messageId, address validator) external view returns (ValidatorVerification memory verification)
Возвращает структуру ValidatorVerification для валидатора и сообщения.
Управление поддерживаемыми доменами
Добавить домен
function addSupportedDomain(uint32 domain) external onlyRole(DEFAULT_ADMIN_ROLE)Удалить домен
function removeSupportedDomain(uint32 domain) external onlyRole(DEFAULT_ADMIN_ROLE)
Эмитят событие SupportedDomainUpdated.
Управление валидаторами
Добавить валидатора
function addValidator(address validator) external onlyRole(DEFAULT_ADMIN_ROLE)Проверяет валидность адреса, максимальное число валидаторов. Выдаёт роль
VALIDATOR_ROLE.Удалить валидатора
function removeValidator(address validator) external onlyRole(DEFAULT_ADMIN_ROLE)Лишает адрес роли валидатора.
Обновление порога кворума
function updateQuorumThreshold(uint256 newThreshold) external onlyRole(DEFAULT_ADMIN_ROLE)
Устанавливает новый порог кворума в базисных пунктах (0 < threshold ≤ 10000).
Получить необходимое количество валидаторов для кворума
function getRequiredValidators() external view returns (uint256 required)
Вычисляет totalValidators * quorumThreshold / 10000.
Проверка поддержки домена
function isDomainSupported(uint32 domain) external view returns (bool supported)
Возвращает, поддерживается ли домен.
Приостановка и возобновление работы (pausable)
pause()— приостановка (только дляPAUSER_ROLE).unpause()— возобновление.
Экстренная верификация сообщения
function emergencyVerifyMessage(bytes32 messageId) external onlyRole(EMERGENCY_ROLE)
Позволяет с ролью EMERGENCY_ROLE принудительно отметить сообщение как проверенное.
Внутренняя проверка подписи валидатора
function _verifyValidatorSignature(bytes32 messageId, bytes calldata signature, address validator) internal pure returns (bool valid)
Восстанавливает адрес из
signatureс помощьюecrecover.Сравнивает с адресом
validator.Проверяет корректность формата подписи.
Поддержка интерфейсов
function supportsInterface(bytes4 interfaceId) public view override returns (bool)
Расширяет поддержку интерфейсов из AccessControl.
Взаимодействие с системой
Использует OpenZeppelin
AccessControlдля управления ролями.Использует
ReentrancyGuardдля защиты от повторного входа.Использует
Pausableдля управления состоянием контракта.Поддерживает взаимодействие с протоколом Hyperlane, обрабатывая сообщения межцепочечного взаимодействия.
Валидаторы подписывают сообщения, и их подписи проверяются в контракте.
Администратор управляет валидаторами и настройками (кворум, поддерживаемые домены).
Важные детали реализации
Сообщения идентифицируются по хешу всего сообщения (
messageId = keccak256(message)).Для верификации требуется собрать подписи от валидаторов, достигших порога кворума.
Тайм-аут верификации — 1 час, после чего статус может быть отмечен как
EXPIRED.Валидация подписей происходит через
ecrecoverс префиксом Ethereum Signed Message.Максимальное количество валидаторов ограничено для оптимизации газа.
Использование кастомных ошибок для снижения затрат на газ.
Контракт поддерживает экстренные операции для восстановления корректного состояния.
Пример использования
// Администратор разворачивает контракт
SymbioticISM ism = new SymbioticISM(adminAddress);
// Администратор добавляет валидаторов
ism.addValidator(validator1);
ism.addValidator(validator2);
// Добавляет поддерживаемые домены
ism.addSupportedDomain(1);
ism.addSupportedDomain(2);
// Пользователь запрашивает проверку сообщения
bytes32 msgId = ism.requestVerification(hyperlaneMessage);
// Валидаторы подписывают и подтверждают сообщение
ism.verifyMessage(msgId, signatureValidator1);
ism.verifyMessage(msgId, signatureValidator2);
// Проверка статуса сообщения
(bool isVerified) = ism.isMessageVerified(msgId);
Диаграмма структуры контракта
classDiagram
class SymbioticISM {
+bytes32 VALIDATOR_ROLE
+bytes32 PAUSER_ROLE
+bytes32 EMERGENCY_ROLE
+uint256 VERIFICATION_TIMEOUT
+uint256 MAX_VALIDATORS_PER_VERIFICATION
+uint256 quorumThreshold
+uint256 totalValidators
+mapping verifications
+mapping validatorVerifications
+mapping supportedDomains
+mapping activeValidators
+constructor(address _admin)
+verify(bytes metadata, bytes message) bool
+requestVerification(HyperlaneMessage message) bytes32
+verifyMessage(bytes32 messageId, bytes signature)
+getVerificationStatus(bytes32 messageId) (VerificationStatus, uint256, uint256)
+isMessageVerified(bytes32 messageId) bool
+getValidatorVerification(bytes32 messageId, address validator) ValidatorVerification
+addSupportedDomain(uint32 domain)
+removeSupportedDomain(uint32 domain)
+addValidator(address validator)
+removeValidator(address validator)
+updateQuorumThreshold(uint256 newThreshold)
+getRequiredValidators() uint256
+isDomainSupported(uint32 domain) bool
+pause()
+unpause()
+emergencyVerifyMessage(bytes32 messageId)
-_verifyValidatorSignature(bytes32 messageId, bytes signature, address validator) bool
+supportsInterface(bytes4 interfaceId) bool
}
class MessageVerification {
+bytes32 messageId
+uint32 origin
+uint32 destination
+bytes32 sender
+bytes32 recipient
+bytes32 bodyHash
+uint256 timestamp
+VerificationStatus status
+uint256 validatorCount
+mapping validatorSigned
}
class ValidatorVerification {
+address validator
+bytes signature
+uint256 timestamp
+bool isValid
}
class HyperlaneMessage {
+bytes32 messageId
+uint32 origin
+uint32 destination
+bytes32 sender
+bytes32 recipient
+bytes body
+bytes metadata
}
SymbioticISM "1" --> "many" MessageVerification : verifications
SymbioticISM "1" --> "many" ValidatorVerification : validatorVerifications
SymbioticISM "1" --> "many" HyperlaneMessage : used in requestVerification
Заключение
Контракт SymbioticISM обеспечивает комплексную систему проверки межцепочечных сообщений в сети Hyperlane с высокой степенью безопасности через кворум валидаторов. Он сочетает в себе гибкое управление ролями, поддержку экстренных сценариев и масштабируемость по количеству валидаторов и доменов. Контракт интегрируется с экосистемой OpenZeppelin, что гарантирует надёжность и безопасность базовых функций.
Документация и архитектура позволяют легко расширять функциональность и интегрировать его в сложные межцепочечные приложения.