حماية MEV مع Jito DontFront

حماية MEV مع Jito DontFront

تشير القيمة القابلة للاستخراج القصوى (MEV) إلى القيمة التي يمكن التقاطها عبر إعادة ترتيب المعاملات أو تضمينها أو استبعادها داخل كتلة. لا تقتصر MEV على سلسلة بلوكشين واحدة؛ بل هي خاصية جوهرية لأي بلوكشين يتحكم فيه منتجو الكتل في ترتيب المعاملات. بعض أشكال MEV، كالمراجحة، تساعد على إبقاء الأسواق فعّالة من خلال تصحيح تفاوتات الأسعار عبر منصات التداول اللامركزية (DEX). أشكال أخرى، كهجمات الساندويتش، تستخرج القيمة مباشرةً من المستخدمين. بالنسبة للمطورين الذين يبنون تطبيقات DeFi، قد يعني ذلك تنفيذ صفقات بأسعار أسوأ وخسارة في الأرباح.

يركّز هذا الدليل على هجمات الساندويتش، وهي إحدى أكثر أشكال MEV الضارة شيوعاً، وكيفية التخفيف منها باستخدام ميزة dontfront من Jito.

القراءة المسبقة الموصى بها: حزم Jito

MEV على سولانا

تعمل بنية سولانا التحتية على تقليص مساحة تعرض MEV مقارنةً بالسلاسل ذات قوائم الانتظار العامة (mempools). إذ تُحال المعاملات مباشرةً إلى قائد الكتلة القادم bedal من الجلوس في قائمة انتظار مشتركة، وتنتهي صلاحية المعاملات غير المعالجة بعد نحو 150 كتلة (~دقيقة واحدة). مما يُضيّق بشكل ملحوظ النافذة الزمنية المتاحة للباحثين لرصد المعاملات المعلّقة والتصرف بناءً عليها.

ومع ذلك، لا تزال عمليات استخراج MEV تقع. إذ يمكن للباحثين الذين يمتلكون بنية تحتية مُحسَّنة واتصالات مباشرة بال validator رصد تدفق المعاملات والاستجابة له. كثير من نشاط MEV على سولانا هو مراجحة ذرية: بوتات تصحّح فوارق الأسعار عبر منصات DEX في معاملة واحدة. يُعدّ هذا النوع من MEV مفيداً بشكل عام، إذ يحسّن اتساق الأسعار عبر الأسواق.

أما النوع الضار، وهو هجمات الساندويتش، فهو ما يجب على المطورين الحماية منه بفاعلية.

ما هو هجوم الساندويتش؟

يحدث هجوم الساندويتش عندما يرصد أحد الباحثين عملية المبادلة (swap) المعلّقة الخاصة بك ويستغل ترتيب المعاملات:

  1. التقدم على المعاملة (Front-run): يشتري الباحث الرمز قبل صفقتك، مما يرفع السعر للأعلى
  2. تُنفَّذ صفقتك بسعر أسوأ مما كان متوقعاً
  3. التعقيب على المعاملة (Back-run): يبيع الباحث الرمز بعد صفقتك، ويجني الفارق في سعره

على سولانا، يمكن أن يحدث هذا من خلال حزم Jito. يُرسل الباحث حزمة معاملات كالتالي: [frontrun_tx, your_tx, backrun_tx]، وينفّذ محرك الكتلة هذه المعاملات بصورة ذرية ومرتّبة. يحصل الضحية على سعر تنفيذ أسوأ بينما يجني الباحث الأرباح من الفارق.

كيف يعمل DontFront

DontFront هي ميزة في محرك كتلة Jito تمنع الباحثين من وضع معاملاتهم قبل معاملتك في الحزمة.

آلية العمل: أضف أي مفتاح عام صالح في سولانا يبدأ بـ jitodontfront إلى أي تعليمة في معاملتك. يتعرف محرك الكتلة على هذا البادئة ويُطبّق قاعدة: أي حزمة تحتوي على معاملتك يجب أن تضعها في الفهرس 0.

Without dontfront: [frontrun_tx, your_tx, backrun_tx] ← sandwich possible
With dontfront: [your_tx, ...] ← your tx must be first

خطوة بخطوة

  1. اختر عنواناً صالحاً يبدأ بـ jitodontfront (مثال: jitodontfront111111111111111111111111111111). لا يحتاج الحساب إلى الوجود على السلسلة؛ فهو لا يُقرأ أو يُكتب إليه أبداً. يمكنك التحقق من أن السلسلة النصية تمثّل عنواناً صالحاً باستخدام دالة assertIsAddress من @solana/kit، أو يمكنك إدخال العنوان في Solana Explorer للتحقق من صحته. إليك مثال على عنوان غير صالح.

  2. أضفه كحساب للقراءة فقط وغير موقِّع إلى أي تعليمة في معاملتك. ضعه للقراءة فقط لتحقيق أفضل سرعة في الوصول للشبكة. تتجاهل معظم البرامج (بما فيها System Program) الحسابات الإضافية التي تتجاوز ما تتوقعه.

  3. أرسل عبر محرك كتلة Jito:

    • sendTransaction: https://mainnet.block-engine.jito.wtf/api/v1/transactions
    • sendBundle: https://mainnet.block-engine.jito.wtf/api/v1/bundles

    التوثيق: sendTransaction وsendBundle

  4. يكتشف محرك الكتلة البادئة 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 متعددة في حزمة واحدة عند استيفاء كلا الشرطين:

  1. جميع معاملات dontfront متجاورة في مقدمة الحزمة
  2. تشترك كل معاملة 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 في واجهة برمجة تطبيقات 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 حول مبالغ الإكراميات لمزيد من التفاصيل حول كيفية تحديد الإكراميات المناسبة.

  • حسّن استخدام وحدات الحوسبة. لكل كتلة عدد محدود من وحدات الحوسبة المتاحة (وللحسابات عدد محدود من وحدات الحوسبة المتاحة لكل كتلة). لضمان تعظيم احتمال تضمين معاملتك/حزمتك في كتلة، ينبغي لك تحسين استخدام وحدات الحوسبة. راجع دليل كيفية تحسين استخدام الحوسبة على سولانا للاطلاع على التفاصيل.

خاص بـ DontFront

  1. ضع علامة على حساب dontfront كقراءة فقط. يعمل التعليم بالكتابة أيضاً لكن القراءة فقط تُحسّن سرعة الوصول للشبكة.

  2. استخدم pubkey فريداً لـ dontfront لكل تطبيق. أي pubkey يبدأ بـ jitodontfront يصلح. استخدام متغيّر فريد (مثل: jitodontfront111111111111111111111111111123) يتيح لك تمييز الاستخدام لكل تطبيق عند فحص البيانات على السلسلة.

  3. يدعم DontFront جداول بحث العناوين (ALT). يمكن تضمين حساب dontfront عبر ALT. لكن لا تستخدم ALTs لحسابات الإكراميات.

القيود

  • محرك الكتلة فقط. يُطبَّق DontFront بواسطة محرك كتلة Jito. المعاملات المرسلة مباشرةً إلى validators (متجاوزةً Jito) ليست محمية.

  • ليس ضماناً. من توثيق Jito: "قد تساعد هذه الميزة في تقليل هجمات الساندويتش لكنها غير مضمونة لذلك، وليست حلاً لجميع أنواع التغييرات في ترتيب المعاملات، بما في ذلك أي ترتيب تجريه أطراف ثالثة."

  • الشبكة الرئيسية/شبكة الاختبار فقط. هذه ميزة من محرك كتلة Jito. لا تعمل على devnet أو localhost.

المراجع

Is this page helpful?