March 7, 2023

Как работают кроссчейн мосты | 4

Всем привет! С вами Тёма!

Сегодня у нас заключительная статья разбора работы кроссчейн мостов. Перевод данной статьи ТЫК

Начнем!

Эта статья посвящена объяснению того, как Wormhole предотвращает атаки повторного воспроизведения VAA (т.е. одно и то же сообщение никогда не может быть доставлено дважды в блокчейн назначения)

Это чрезвычайно важно, поскольку в противном случае злоумышленники могут украсть токены, получая токены с одним и тем же VAA многократно

Как предотвратить двойную доставку одного и того же сообщения (повтор VAA)?

По сути, каждый успешно погашенный VAA должен запоминаться глобально, поддерживая он-чейн флаг, указывающий на то, что VAA уже был погашен

Любые транзакции, которые пытаются повторно использовать VAA, отмеченные флагом is_already_redeemed, будут отклонены

Далее мы объясним, как это реализовано на Solana и Ethereum

На Solana функции доставки конечного сообщения (complete_native и complete_wrapped) принимают входной аккаунт PDA claim и используют ее для предотвращения двойного подписания VAA:

При вызове, аккаунт claim не должен быть инициализирован:

Функция consume вызывается для инициализации и проверки достоверности аккаунта claim:

Аккаунт claim - это PDA, определяемый по emitter_address, emitter_chain и sequence из VAA:

Аккаунт claim имеет флаг claimed, который становится true после инициализации (строка 87):

Благодаря вышеизложенному, Wormhole гарантирует, что каждый VAA с уникальной комбинацией (emitter_address, emitter_chain и sequence) создает уникальный аккаунт claim, который может быть успешно использован только один раз

Аналогично на Ethereum, Wormhole ведет глобальный mapping completedTransfers, в которой хранятся хэши всех завершенных VAA:

Хеш VAA - это хеш keccak256 на байтах VAA (за исключением подписей опекунов):

Это гарантирует, что каждый хэш VAA уникален для одного и того же сообщения, даже если опекуны разные

При каждом вызове доставки сообщения проверяется, помечен ли уже хэш VAA (строка 497 isTransferCompleted), и прерывается, если true, иначе доставляется сообщение и помечается хэш (строка 498 setTransferCompleted)

В приведенном выше примере _state.completedTransfers - это mapping в глобальном хранилище, и он должен обновляться при каждой успешной передаче сообщения:

Обратите внимание, что в Ethereum операции с глобальным хранилищем (SSTORE) требуют наибольших затрат газа. Это объясняет, почему погашение токена обходится дорого. Например, в следующей транзакции вызов completeTransfer стоит $6,81 (270K газа):

Надеюсь статья была интересной и понятной!

Все мои ресурсы - https://t.me/ortomich_links