Как работают кроссчейн мосты | 3
Сегодня мы снова продолжим разбираться с работой кроссчейн мостов, а поможет нам в этом данная статья ТЫК
Начнем!
Как продолжение к части 1 и части 2, эта статья посвящена объяснению того, как Wormhole обеспечивает корректность передаваемых по мосту токенов
Здесь "корректный" означает, что и тип токена, и переданная сумма совпадают или эквивалентны токену, переданному на исходной сети.
Как удостовериться, что перенесённый токен корректен?
В VAA информация о токене указывается в payload из VAA с помощью tokenChain и tokenAddress:
Обратите внимание, что токен не обязательно является токеном чейна-отправителя или чейна-получателя, это может быть адрес токена в любой сети. Например, Алиса может перевести USDC из Solana (tokenChain 1) в Polygon (tokenChain 5), а токен, указанный в VAA, может быть USD Coin (USDC) на Ethereum (tokenAddress 0xa0b8, tokenChain 2)
Для того, чтобы токен, указанный в VAA, перевести в правильный токен на целевом блокчейне, в Wormhole есть функция под названием "аттестация токенов", которая позволяет пользователям регистрировать токены. Скажем, если Алиса хочет зарегистрировать новый токен на Solana, который соответствует существующему токену X на Ethereum, процесс будет выглядеть следующим образом:
1. Алиса может вызвать функцию attestToken на контракте Wormhole Token Bridge блокчейна происхождения (в данном случае Ethereum) с tokenAddress токена X и nonce:
Функция attestToken опубликует сообщение, содержащее метаданные токена, включая tokenAddress, tokenChain (2 для Ethereum), decimals токена, symbol и name:
2. Сообщение будет наблюдаться опекунами, которые затем создадут аттестат VAA, который можно получить, используя sequence, возвращенный функцией attestToken
3. Затем Алиса может предоставить аттестат VAA каждой другой сети с помощью функции CreateWrapped моста Wormhole Token Bridge на другой сети (например, create_wrapped на Solana):
В приведённом выше примере вызов create_wrapped с аттестатом VAA и минтом токена установит соответствие между аттестованным токеном и минтом токена
Обратите внимание, что минт токена должен быть уникальным: два разных аттестованных токена должны соответствовать разным минтам. В Solana это достигается путем создания PDA из метаданных аттестованного токена (chain, token_address, original_decimals):
PDA - это адрес минта, соответствующий исходному токену. При выкупе токена на Solana минт может быть проверен с помощью verify_derivation на PDA (wrapped_meta):
Поскольку адресом минта является PDA, только программа Wormhole Token Bridge имеет право минтить соответствующие токены. Это гарантирует, что любой может вызвать create_wrapped с аттестацией VAA (если минт не был зарегистрирован), но злоумышленник не сможет подделать mint
Если злоумышленник вызовет create_wrapped до Алисы и предоставит неправильный минт, например, Dogecoin D56d на Solana), зарегистрированный вместо ETH - Ether (Portal) для WETH на Ethereum, то проверка в accs.mint.verify_derivation(ctx.program_id, &derivation_data) будет неудачной
На других чейнах процесс аналогичен. Например, на Ethereum функция createWrapped развертывает новый контракт для токена (создавая Wormhole-Wrapped Token) и вызывает функцию setWrappedAsset для обновления маппинга wrappedAsset, хранящей (tokenChainId, tokenAddress) и обернутый адрес wrapper:
При погашении токена на Ethereum маппинг wrappedAsset затем используется для получения соответствующего токена из tokenChainId и tokenAddress:
Функции завершения передачи (CompleteNative и CompleteWrapped) проверяют равенство монет, как показано ниже:
Одна оговорка заключается в том, что получатель to, указанный пользователем, должен быть валидным получателем токена. Например, на Solana это означает, что получатель должен быть токен-аккаунтом с тем же mint, что и PDA, созданный в create_wrapped
Если (из-за ошибки пользователя) адрес получателя не является аккаунтом токена, или его минт токена не соответствует PDA с сидами (chain, token_address, original_decimals), то пользователь никогда не сможет получить токен
Токен может быть заблокирован на мосту навсегда, пока сеть происхождения не выпустит новый VAA с правильным адресом получателя
Как убедиться, что сумма перенесённого токена верна?
VAA содержит сумму передачи uint256 amount, которая гарантирует, что количество сминченного токена на блокчейне-получателе должно соответствовать amount. Однако техническая проблема здесь заключается в том, что перенесённые токены могут иметь разные decimals. Например, Ether имеет decimals=18 на Ethereum, но Wormhole ограничивает decimals токенов до 8 (строка 147 в коде ниже):
Чтобы решить эту проблему, Wormhole должен убедиться, что decimals токенов обрабатываются правильно. Если токен имеет decimals>8 (например, Ether), то Wormhole должен нормализовать передаваемую сумму относительно ограничения в 8
Более конкретно, при кодировании amount в payload из VAA, Wormhole денормализует сумму перевода, вызывая команды deNormalizeAmount и deNormalizeAmount:
В приведенном выше коде (строки 278 и 285), если decimals больше 8, amount сдвигается на decimals -8 (вправо и влево соответственно)
Обратите внимание, что из-за десятичного сдвига депозитная пыль (мелочь, dust) не будет передана целевому блокчейну, и Wormhole вернет пыль (если таковая имеется) отправителю на исходном блокчейне:
Надеюсь статья была интересной и понятной!