Захист від MEV за допомогою Jito DontFront
Максимально видобувна вартість (MEV) — це вартість, яку можна отримати шляхом перевпорядкування, включення або виключення транзакцій у блоці. MEV не є унікальною властивістю жодного конкретного ланцюга — це фундаментальна характеристика будь-якого блокчейну, де виробники блоків контролюють порядок транзакцій. Деякі форми MEV, наприклад арбітраж, сприяють ефективності ринків, виправляючи цінові розбіжності між DEX. Інші, як-от сендвіч-атаки, витягують вартість безпосередньо від користувачів. Для розробників DeFi-застосунків це може означати гіршу якість виконання торгів і втрачений прибуток.
Цей посібник зосереджений на сендвіч-атаках — поширеній формі шкідливого MEV —
та способах їх пом'якшення за допомогою функції dontfront від Jito.
Рекомендована попередня підготовка: Jito Bundles
MEV у Solana
Архітектура Solana вже зменшує площу атаки MEV порівняно з ланцюгами з відкритими мемпулами. Транзакції пересилаються безпосередньо до майбутнього лідера блоку, а не очікують у спільному мемпулі, а необроблені транзакції закінчуються приблизно після 150 блоків (~1 хвилина). Це суттєво звужує вікно для пошуковиків, що спостерігають за очікуваними транзакціями та реагують на них.
Проте видобуток MEV все одно відбувається. Пошуковики з оптимізованою інфраструктурою та прямими підключеннями до validator можуть спостерігати потоки транзакцій і реагувати на них. Значна частина активності MEV у Solana — це атомарний арбітраж: боти, що виправляють цінові розбіжності між DEX в межах однієї транзакції. Цей тип MEV загалом є корисним, оскільки підвищує цінову узгодженість між ринками.
Шкідлива різновидність — сендвіч-атаки — це те, від чого розробникам слід активно захищатися.
Що таке сендвіч-атака?
Сендвіч-атака відбувається, коли пошуковик виявляє ваш очікуваний своп та експлуатує порядок транзакцій:
- Випереджальна угода (front-run): пошуковик купує токен до вашої угоди, підштовхуючи ціну вгору
- Ваша угода виконується за гіршою ціною, ніж очікувалося
- Завершальна угода (back-run): пошуковик продає токен після вашої угоди, кладучи різницю собі в кишеню
У Solana це може відбуватися через
Jito bundles. Пошуковик
подає пакет транзакцій на кшталт:
[frontrun_tx, your_tx, backrun_tx], і блок-рушій виконує їх
атомарно у зазначеному порядку. Жертва отримує гіршу ціну виконання, тоді як
пошуковик отримує прибуток від спреду.
Як працює DontFront
DontFront — це функція блок-рушія Jito, яка не дає пошуковикам розміщувати транзакції перед вашою у пакеті.
Принцип роботи: додайте будь-який дійсний публічний ключ Solana, що починається
з jitodontfront, до будь-якої інструкції у вашій транзакції. Блок-рушій
розпізнає цей префікс і застосовує правило: будь-який пакет, що містить вашу
транзакцію, повинен розміщувати її на індексі 0.
Without dontfront: [frontrun_tx, your_tx, backrun_tx] ← sandwich possibleWith dontfront: [your_tx, ...] ← your tx must be first
Покрокова інструкція
-
Оберіть дійсну адресу, що починається з
jitodontfront(наприклад,jitodontfront111111111111111111111111111111). Обліковий запис не повинен існувати в мережі; він ніколи не читається і не записується. Ви можете перевірити, чи є рядок дійсною адресою, за допомогою функціїassertIsAddressз @solana/kit, або ввести адресу в Solana Explorer, щоб перевірити, чи вона розпізнається. Ось приклад недійсної адреси. -
Додайте її як обліковий запис лише для читання без підпису до будь-якої інструкції у вашій транзакції. Позначте як лише для читання для оптимальної швидкості підтвердження. Більшість програм (включаючи System Program) ігнорують додаткові облікові записи, що виходять за межі їхніх очікувань.
-
Надішліть через блок-рушій Jito:
sendTransaction:https://mainnet.block-engine.jito.wtf/api/v1/transactionssendBundle:https://mainnet.block-engine.jito.wtf/api/v1/bundles
Документація: sendTransaction та sendBundle
-
Блок-рушій виявляє префікс
jitodontfrontі застосовує правила впорядкування.
Що відбувається на рівні блок-рушія
Коли блок-рушій бачить транзакцію, що містить обліковий запис jitodontfront:
- Через
sendTransaction: транзакція захищена. Жоден пакет не може розмістити іншу транзакцію перед нею - Через
sendBundle: транзакція повинна знаходитися на індексі 0, інакше весь пакет буде відхилено
Транзакції та пакети, що не містять облікового запису jitodontfront,
не зачіпаються.
Правила впорядкування пакетів
Ці правила застосовуються, коли транзакція з jitodontfront присутня у пакеті.
Дозволені шаблони
[tx_with_dontfront, tip][tx_with_dontfront, arbitrage, tip][tx_with_dontfront_signer1, tx_with_dontfront_signer1_and_signer2, tip]
Кілька транзакцій DontFront в одному пакеті
Кілька dontfront-транзакцій в одному пакеті дозволені, якщо виконуються обидві умови:
- Всі dontfront-транзакції йдуть підряд на початку пакету
- Кожна dontfront-транзакція має принаймні одного спільного підписанта з першою dontfront-транзакцією
✅ [txA_df, txB_df, txC_df, arbitrage, tip](contiguous at front, overlapping signers)✅ [txA_df_signer1_signer2, txB_df_signer1_signer3, txC_df_signer2_signer4](each shares a signer with txA)
Заборонені шаблони
❌ [tip, tx_with_dontfront]→ dontfront tx is not at index 0❌ [txA_df_signer1, txB_df_signer2]→ no overlapping signer between txA and txB❌ [trade, tx_with_dontfront, arbitrage, tip]→ dontfront tx is not at the front
Приклади інтеграції
Для швидкого прикладу коду дивіться запис у кулінарній книзі MEV Protection.
TypeScript (@solana/kit)
Основна ідея — допоміжна функція, яка додає обліковий запис dontfront до будь-якої інструкції:
import {address,AccountRole,type Instruction,type Address} from "@solana/kit";const DONT_FRONT: Address = address("jitodontfront111111111111111111111111111111");function withDontFront(ix: Instruction): Instruction {return {...ix,accounts: [...(ix.accounts ?? []),{ address: DONT_FRONT, role: AccountRole.READONLY }]};}
Потім надішліть підписану транзакцію до блок-рушія Jito замість стандартного RPC-вузла. Завжди використовуйте кодування base64. Base58 є застарілим у API Jito.
const response = await fetch("https://mainnet.block-engine.jito.wtf/api/v1/transactions",{method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify({jsonrpc: "2.0",id: 1,method: "sendTransaction",params: [base64Tx, { encoding: "base64" }]})});
Найкращі практики
DontFront — це один рівень захисту. Надійна стратегія пом'якшення MEV поєднує кілька підходів:
Захист на рівні транзакцій
-
Встановлюйте жорсткі допуски прослизання. Найефективніший захист від сендвіч-атак — обмеження допустимого прослизання при свопах. Менше вікно прослизання зменшує маржу прибутку для зловмисників, роблячи вашу транзакцію менш привабливою для сендвіча.
-
Встановлюйте відповідні чайові та пріоритетні комісії. Під час перевантаження вищі чайові та пріоритетні комісії підвищують імовірність швидкого підтвердження вашої транзакції/пакету, скорочуючи вікно для дій пошуковиків. Дивіться документацію Jito щодо розмірів чайових для детальнішої інформації про встановлення відповідних чайових.
-
Оптимізуйте використання обчислювальних одиниць. Кожен блок має обмежену кількість доступних обчислювальних одиниць (і облікові записи мають обмежену кількість обчислювальних одиниць, доступних на блок). Щоб максимізувати ймовірність включення вашої транзакції/пакету до блоку, слід оптимізувати використання обчислювальних одиниць. Дивіться посібник How to Optimize Compute Usage on Solana для деталей.
Специфічні поради для DontFront
-
Позначайте обліковий запис dontfront як лише для читання. Позначення як записуваного теж працює, але лише для читання оптимізує швидкість підтвердження.
-
Використовуйте унікальний pubkey dontfront для кожного застосунку. Будь-який pubkey, що починається з
jitodontfront, підходить. Використання унікального варіанту (наприклад,jitodontfront111111111111111111111111111123) дозволяє розрізняти використання по застосунках при перегляді даних у мережі. -
DontFront підтримує таблиці пошуку адрес. Обліковий запис dontfront може бути включений через ALT. Але не використовуйте ALT для облікових записів чайових.
Обмеження
-
Лише блок-рушій. DontFront застосовується блок-рушієм Jito. Транзакції, надіслані безпосередньо до validator (в обхід Jito), не захищені.
-
Не є гарантією. З документації Jito: «Ця функція може допомогти зменшити сендвіч-атаки, але не гарантує цього і не є рішенням для всіх варіацій упорядкування транзакцій, включаючи будь-яке впорядкування, що здійснюється третіми сторонами.»
-
Лише Mainnet/Testnet. Це функція блок-рушія Jito. Вона не працює в devnet або localhost.
Посилання
Is this page helpful?