Три слоя доказательства не заменяют друг друга
СлойОбязательные поляЧто он доказывает
Sourcetx hash, canonical block, emitterChain, emitterAddress, sequenceКакое on-chain сообщение наблюдали Guardians
VAAbody bytes, digest, guardianSetIndex, signaturesЧто supermajority подписало именно это тело
Destinationchain, receiving app, VAA/message hash, result event или stateЧто нужное приложение обработало сообщение
Три слоя доказательства не заменяют друг друга
Слой
Source
Обязательные поля
tx hash, canonical block, emitterChain, emitterAddress, sequence
Что он доказывает
Какое on-chain сообщение наблюдали Guardians
Слой
VAA
Обязательные поля
body bytes, digest, guardianSetIndex, signatures
Что он доказывает
Что supermajority подписало именно это тело
Слой
Destination
Обязательные поля
chain, receiving app, VAA/message hash, result event или state
Что он доказывает
Что нужное приложение обработало сообщение

Тройка emitter идентифицирует сообщение только после проверки source history

VAA индексируется по emitter_chain, 32-байтовому Wormhole-formatted emitter_address и sequence этого emitter. Sequence — счётчик сообщений конкретного emitter, а не nonce пользовательского кошелька и не номер source-транзакции. Из source tx сохраните событие Core Contract и декодируйте эти три поля; адрес приложения из интерфейса не заменяет emitter_address в самом событии.

Одинаковая на вид тройка безопасно связывает историю только при каноничном source block. Документация Wormhole отдельно предупреждает о reorg при низком consistency level: разные ветви цепочки могут породить разные тела. Проверьте source finality и реорганизации по правилам выбранной сети; только затем фиксируйте tuple и payload.

Header выбирает guardian set, а подписи относятся к хешу body

Header содержит version, guardian_set_index и массив signatures. Body содержит timestamp, nonce, emitter_chain, emitter_address, sequence, consistency_level и payload. Подписываемый digest получают двойным keccak256 от точных bytes body. Перекодирование payload, адреса или чисел создаёт другой digest, даже если текстовая карточка выглядит одинаково.

Проверка VAA без доверия к одной карточке

  1. 1
    Получить исходные bytes

    Найдите VAA через официальный SDK или Wormholescan по source tx либо emitter tuple. Сохраните serialized bytes и сеть, а не только статус.

  2. 2
    Разобрать body

    Сверьте emitterChain, emitterAddress, sequence, consistencyLevel и application payload с source event. Несовпадение любого поля останавливает проверку.

  3. 3
    Посчитать digest

    Используйте реализацию Wormhole SDK или Core Contract: спецификация подписывает double-keccak body. Не заменяйте её обычным хешем всей VAA.

  4. 4
    Выбрать guardian set

    Получите set по guardianSetIndex, проверьте уникальные индексы signer и достаточный supermajority, а на destination Core — что этот set ещё принимается. Текущее описание сети приводит 13 из 19, но код не должен зашивать это число навсегда.

  5. 5
    Проверить подписи

    Проверяйте ECDSA над точным digest через официальный Core/SDK path. Количество байтов в массиве ещё не доказывает валидный quorum.

Если источник и VAA расходятся, сначала исключите неверную сеть, Wormhole-formatted address и другую ветвь цепочки. Устройство RPC объясняет, почему один сервер может ещё не видеть каноничный source block; другой API-ответ не разрешает игнорировать несовпавшее тело.

Redemption ищут в receiving application, а не в header VAA

Базовый VAA не содержит универсального destination и фактически multicast: любой Core Contract сети Wormhole может проверить его подлинность. Назначение и действие определяет application payload. Поэтому сначала декодируйте формат конкретного протокола, установите destination chain и receiving contract, а затем ищите его on-chain result.

Как интерпретировать найденные следы
НаблюдениеДоказанный этапЧего ещё не хватает
Source event есть, VAA нетСообщение опубликованоFinality, guardian observation или quorum
VAA signatures валидныGuardians аттестовали bodyОбработка receiving application
Explorer показывает destination txЕсть кандидат на доставкуValidated receipt и app-specific result
Receiving contract пометил message consumedЭто приложение обработало VAAПроверка ожидаемого state change
Повторный submit отклонён как consumedReplay protection сработалаЭто не доказывает, что первый вызов дал нужный бизнес-результат
Как интерпретировать найденные следы
Наблюдение
Source event есть, VAA нет
Доказанный этап
Сообщение опубликовано
Чего ещё не хватает
Finality, guardian observation или quorum
Наблюдение
VAA signatures валидны
Доказанный этап
Guardians аттестовали body
Чего ещё не хватает
Обработка receiving application
Наблюдение
Explorer показывает destination tx
Доказанный этап
Есть кандидат на доставку
Чего ещё не хватает
Validated receipt и app-specific result
Наблюдение
Receiving contract пометил message consumed
Доказанный этап
Это приложение обработало VAA
Чего ещё не хватает
Проверка ожидаемого state change
Наблюдение
Повторный submit отклонён как consumed
Доказанный этап
Replay protection сработала
Чего ещё не хватает
Это не доказывает, что первый вызов дал нужный бизнес-результат

Для token transfer проверяют контракт соответствующего продукта, его transfer-completed state или событие и изменения токена. Для произвольного message это может быть другой receiver и другая replay-защита. Общий материал про мосты помогает назвать этапы, но не подменяет emitter tuple, VAA digest и app-specific consumption.

На EVM destination transaction может успешно попасть в блок, а inner call receiving contract — завершиться иначе; receipt, logs и trace отвечают на разные части вопроса. Проверка внутренних вызовов нужна, когда внешний status не объясняет, применил ли receiver payload.

Повторная доставка допустима только после доказательства состояния consumption

  • не отправляйте VAA в адрес контракта, взятый из поисковой рекламы или чата;
  • не заменяйте emitter_address адресом пользовательского кошелька;
  • не считайте len_signatures доказательством валидных signer и quorum;
  • не отправляйте VAA, если destination Core уже отклоняет его guardian set как expired;
  • не называйте source tx финальным, не проверив consistency level и canonical block;
  • не повторяйте redeem, пока не проверены destination receipt и consumption state;
  • не передавайте seed-фразу, private key или подпись кошелька для чтения публичного VAA.

Если VAA валиден, но destination state отсутствует, сохраните bytes, tuple, digest, guardianSetIndex, source finality и все destination tx hashes. После этого повторяют только официальный app-specific delivery path. Если message уже consumed, новый submit не является восстановлением; разбирать нужно результат первого вызова.

Если target Core отвергает исторический guardian set как expired, подписи старых ключей уже недостаточны для redemption. Не переписывайте header вручную: официальный recovery-flow получает observations текущего set, заменяет устаревшие подписи, повторно проверяет тот же body и требует завершить Guardian approval. Локально пересобранные bytes нельзя считать одобренным VAA до этого финального шага.

Источники

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

  1. Wormhole Docs — Verified Action Approvals Wormhole Foundation · Проверено 30 августа 2026 г. в 15:40 GMT+5
  2. Wormhole Docs — Security Wormhole Foundation · Проверено 30 августа 2026 г. в 15:40 GMT+5
  3. Wormhole Docs — Fetch a Signed VAA Wormhole Foundation · Проверено 30 августа 2026 г. в 15:40 GMT+5
  4. Wormhole Docs — Consistency Levels Wormhole Foundation · Проверено 30 августа 2026 г. в 15:40 GMT+5
  5. Wormhole Docs — Replace Outdated Signatures in VAAs Wormhole Foundation · Проверено 30 августа 2026 г. в 15:40 GMT+5
Материал носит информационный характер и не является индивидуальной рекомендацией. Криптоактивы связаны с риском волатильности, технических сбоев, хищения и полной потери средств.