Обратная совместимость — это способность новой версии библиотеки корректно работать с кодом, написанным для предыдущих версий, без необходимости значительных изменений. В контексте Universal Router это особенно важно, поскольку он используется для построения сложных транзакций в экосистеме децентрализованных финансов, где стабильность интерфейсов критична.
Universal Router объединяет несколько протоколов (например, обмены токенов, NFT-транзакции и маршрутизацию ликвидности) в едином контракте. Любые изменения в его API или внутренней логике могут повлиять на существующие интеграции, поэтому разработчики библиотеки придерживаются строгих принципов совместимости.
1. API-совместимость (Application Programming Interface) Сохранение сигнатур функций и структуры вызовов:
2. Совместимость формата данных Universal Router использует закодированные команды (commands) и параметры (inputs). Обратная совместимость требует:
3. Поведенческая совместимость Даже при сохранении API поведение функций не должно неожиданно изменяться:
Universal Router использует систему команд, где каждая операция кодируется байтом. Для поддержки обратной совместимости:
Пример структуры:
const commands = [
0x00, // V2_SWAP_EXACT_IN
0x01, // V2_SWAP_EXACT_OUT
0x02, // PERMIT2_TRANSFER_FROM
];
Добавление новой команды:
const NEW_COMMAND = 0x10; // не конфликтует со старыми
Каждая команда сопровождается параметрами, закодированными в
bytes. Для поддержки старых версий:
Пример:
function decodeInput(command, input) {
switch (command) {
case 0x00:
return decodeV2Swap(input);
case 0x10:
return decodeNewFeature(input);
default:
throw new Error("Unsupported command");
}
}
В старых версиях маршруты обмена могли формироваться иначе. Новые версии Universal Router:
Universal Router чаще реализуется как immutable контракт (без возможности обновления). Это означает:
В некоторых случаях используется прокси:
JavaScript-обертки над Universal Router играют ключевую роль в обеспечении совместимости.
SDK часто поддерживает несколько версий одновременно:
import { UniversalRouterV1, UniversalRouterV2 } from 'universal-router-sdk';
Иногда версия определяется автоматически:
function getRouter(version) {
if (version === 1) return new UniversalRouterV1();
return new UniversalRouterV2();
}
При устаревании функций:
Пример:
function oldSwap() {
console.warn("Deprecated: use newSwap instead");
return newSwap();
}
Проверяют, что старый функционал не сломан:
Фиксируют состояние:
1. Изменение порядка аргументов Приводит к некорректным вызовам.
2. Изменение кодировки данных Ломает декодирование старых транзакций.
3. Удаление команд Старые транзакции становятся невыполнимыми.
4. Изменение логики gas-расчёта Может привести к неудачным транзакциям.
Добавление новой функции без нарушения старой:
class UniversalRouter {
swapExactTokensForTokens(params) {
// старая логика
}
swapWithPermit(params) {
// новая функция
}
}
Старый код:
router.swapExactTokensForTokens(...)
Новый код:
router.swapWithPermit(...)
Обе версии продолжают работать параллельно.
ABI (Application Binary Interface) определяет, как взаимодействовать с контрактом:
Universal Router интегрируется с:
Для сохранения совместимости:
Используется семантическое версионирование (SemVer):
Пример:
v1.2.3 → v1.3.0 (добавлены функции)
v1.3.0 → v2.0.0 (сломана совместимость)
Обратная совместимость в Universal Router — это не просто удобство, а критически важный элемент стабильности всей системы взаимодействия с блокчейном.