اضغط على ESC للإغلاق

Anti-MEV Stealth Swap: المواجهة النهائية - الإرسال و CLI

حسنًا، في المقلين السابقين قمنا بإنشاء "قناة اتصال آمنة" وكتابة منطق المبادلة (Swap). في هذا الجزء الأخير، سنقوم بإنهاء بناء الأداة. سنقوم بتنفيذ حلقة انتظار الكتل (Blocks) وتغليف كل ذلك في واجهة سطر أوامر (CLI) مريحة.

1. منطق الإرسال: لماذا لا يمكنك ببساطة النقر على "إرسال"؟

تنشئ شبكة إيثيريوم كتلًا كل 12 ثانية تقريبًا. حزمتك (Bundle) صالحة فقط لرقم كتلة محدد. إذا لم يتم تضمينها في الكتلة الأقرب (بسبب انخفاض رسوم الغاز مثلاً)، فستحتاج إلى إعادة بنائها للكتلة التالية برقم محدث.

سنستخدم حلقة تكرارية (Loop) تحاول "دفع" عملية المبادلة الخفية (Stealth Swap) عبر الكتل العشر القادمة.

 

2. الكود: تنفيذ الإرسال وواجهة سطر الأوامر (CLI)

لنقم بإضافة الطريقة النهائية sendBundle ومعالجة بسيطة للمدخلات من سطر الأوامر.

import { FlashbotsBundleResolution } from "@flashbots/ethers-provider-bundle";

async function runStealthSwap(amountInEth: string) {
    const { wallet, flashbotsProvider, provider } = await initStealthProvider();
    const amountIn = ethers.parseEther(amountInEth);
    let currentBlock = await provider.getBlockNumber();

    console.log(`البدء عند الكتلة: ${currentBlock}`);

    // نحاول إرسال الحزمة خلال الكتل العشر القادمة
    for (let i = 0; i < 10; i++) {
        const targetBlock = currentBlock + i;
        
        // إعادة بناء الحزمة لكتلة محددة (بما في ذلك المحاكاة)
        const signedBundle = await createAndSimulateBundle(wallet, flashbotsProvider, provider, amountIn, targetBlock);
        
        if (!signedBundle) continue;

        const bundleSubmission = await flashbotsProvider.sendBundle(signedBundle, targetBlock);
        
        if ("error" in bundleSubmission) {
            console.error(`خطأ في الإرسال: ${bundleSubmission.error.message}`);
            continue;
        }

        console.log(`تم إرسال الحزمة. بانتظار الكتلة ${targetBlock}...`);
        const waitResponse = await bundleSubmission.wait();
        
        if (waitResponse === FlashbotsBundleResolution.BundleIncluded) {
            console.log(`انتصار! تم تضمين المعاملة في الكتلة ${targetBlock}`);
            console.log(`الهاش: https://etherscan.io/tx/${(await signedBundle)[0].hash}`); // هاش تقريبي
            return;
        } else if (waitResponse === FlashbotsBundleResolution.BlockPassedWithoutInclusion) {
            console.log(`لم يتم التضمين. مرت الكتلة ${targetBlock} بدوننا. نحاول مرة أخرى...`);
        } else if (waitResponse === FlashbotsBundleResolution.AccountNonceTooHigh) {
            console.error("خطأ: الـ Nonce مرتفع جدًا. تحقق من المعاملات المعلقة.");
            return;
        }
    }
}

// واجهة CLI بسيطة
const amount = process.argv[2] || "0.01";
runStealthSwap(amount);

بالطبع، ما قمنا به حتى الآن هو مجرد "أهلاً بالعالم" في Flashbots للمبادلة على Uniswap V3. لكي يكون لهذا الأداة فائدة حقيقية في الظروف الواقعية، نحتاج إلى تحسين المنطق قليلاً.

 

import { ethers } from "ethers";
import { FlashbotsBundleProvider, FlashbotsBundleResolution } from "@flashbots/ethers-provider-bundle";
import * as dotenv from "dotenv";

dotenv.config();

const WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const ROUTER = "0xE592427A0AEce92De3Edee1F18E0157C05861564";
const QUOTER = "0x61fFe014bA17989E743c5F6cB21bF9697530B21e";

const ABI = [
    "function exactInputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 deadline, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96)) external returns (uint256 amountOut)",
    "function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96)) external returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)",
    "function approve(address spender, uint256 amount) external returns (bool)",
    "function allowance(address owner, address spender) external view returns (uint256)",
    "function balanceOf(address account) external view returns (uint256)"
];

async function main() {
    const provider = new ethers.JsonRpcProvider(process.env.ETH_RPC_URL);
    const wallet = new ethers.Wallet(process.env.SENDER_PRIVATE_KEY, provider);
    const authSigner = new ethers.Wallet(process.env.FLASHBOTS_AUTH_KEY, provider);
    const flashbots = await FlashbotsBundleProvider.create(provider, authSigner);

    const quoter = new ethers.Contract(QUOTER, ABI, provider);
    const weth = new ethers.Contract(WETH, ABI, wallet);

    const baseAmount = ethers.parseEther(process.argv[2] || "0.1");
    const minThreshold = ethers.parseUnits(process.argv[3] || "200", 6);

    // --- التحقق المسبق ---
    const balance = await weth.balanceOf(wallet.address);
    if (balance < baseAmount) throw new Error("رصيد WETH غير كافٍ");

    const allowance = await weth.allowance(wallet.address, ROUTER);
    if (allowance < baseAmount) {
        await (await weth.approve(ROUTER, ethers.MaxUint256)).wait();
    }

    let nonce = await wallet.getNonce();
    let lastQuote = 0n;
    let lastExecutionBlock = 0;

    provider.on("block", async (block) => {
        try {
            // --- تخطي عشوائي (لإرباك أنماط التتبع) ---
            if (Math.random() < 0.6) return;

            const quote = await quoter.quoteExactInputSingle.staticCall({
                tokenIn: WETH,
                tokenOut: USDC,
                amountIn: baseAmount,
                fee: 3000,
                sqrtPriceLimitX96: 0
            });

            // --- الحد الأدنى للربحية ---
            if (quote.amountOut < minThreshold) return;

            // --- اكتشاف التغيير ---
            if (lastQuote !== 0n) {
                const diff = (quote.amountOut * 1000n) / lastQuote;
                // تجاهل إذا كان التغيير أقل من 0.3%
                if (diff > 997n && diff < 1003n) return;
            }

            // --- فترة تهدئة (Cool Down) ---
            if (block - lastExecutionBlock < 2) return;

            // --- مبلغ عشوائي (لكسر توقيع المعاملة) ---
            const randomFactor = BigInt(95 + Math.floor(Math.random() * 10)); // 95–105%
            const amountIn = (baseAmount * randomFactor) / 100n;

            // --- الانزلاق السعري (Slippage) ---
            const minOut = (quote.amountOut * 995n) / 1000n;

            const feeData = await provider.getFeeData();
            const tx = {
                to: ROUTER,
                data: new ethers.Interface(ABI).encodeFunctionData("exactInputSingle", [{
                    tokenIn: WETH,
                    tokenOut: USDC,
                    fee: 3000,
                    recipient: wallet.address,
                    deadline: Math.floor(Date.now() / 1000) + 90,
                    amountIn: amountIn,
                    amountOutMinimum: minOut,
                    sqrtPriceLimitX96: 0
                }]),
                chainId: 1,
                type: 2,
                gasLimit: 250000,
                maxFeePerGas: feeData.maxFeePerGas,
                maxPriorityFeePerGas: feeData.maxPriorityFeePerGas || 2n,
                nonce: nonce
            };

            const signed = await flashbots.signBundle([{ signer: wallet, transaction: tx }]);
            const target = block + 1;

            const sim = await flashbots.simulate(signed, target);
            if ("error" in sim) return;

            const sub = await flashbots.sendBundle(signed, target);
            if ("error" in sub) return;

            const res = await sub.wait();
            nonce++; // مهم جداً
            if (res === FlashbotsBundleResolution.BundleIncluded) {
                console.log("تم التنفيذ في الكتلة:", target);
                process.exit(0);
            }

            lastQuote = quote.amountOut;
            lastExecutionBlock = block;
        } catch (e) {
            // وضع صامت عند الأخطاء
        }
    });
}

main();

 

3. كيف تستخدم Anti-MEV Stealth Swap

1. التثبيت

npm install ethers @flashbots/ethers-provider-bundle dotenv

2. أنشئ ملف .env

ETH_RPC_URL=https://mainnet.infura.io/v3/YOUR_KEY
SENDER_PRIVATE_KEY=YOUR_PRIVATE_KEY
FLASHBOTS_AUTH_KEY=ANY_NEW_PRIVATE_KEY

3. تجهيز المحفظة

ضروري جداً:

  • يجب أن يكون لديك إيثيريوم (ETH) في المحفظة لرسوم الغاز.
  • وإيثيريوم مغلف (WETH) لعملية المبادلة نفسها.

إذا لم يكن لديك WETH: قم بتحويل ETH إلى WETH عبر أي منصة (مثل Uniswap).

4. التشغيل

node app.js 0.1 200

حيث:

  • 0.1 -> كمية WETH التي تريد مبادلتها.
  • 200 -> الحد الأدنى المقبول من USDC في المقابل.

5. كيف يعمل البرنامج؟

بعد البدء:

  • يتحقق من رصيد WETH.
  • يقوم بالموافقة (Approve) مرة واحدة فقط.
  • يبدأ بمراقبة كل كتلة جديدة.
  • في كل كتلة:
    • يتخطى أحياناً بشكل عشوائي للتمويه.
    • يتحقق من السعر عبر الـ Quoter.
    • يتحقق من حد الربحية الخاص بك.
    • يتحقق من حركة السعر (لتجنب الركود).
    • يغير مبلغ المعاملة قليلاً للتمويه.
    • يقوم بالمحاكاة.
    • يرسل عبر Flashbots.

6. متى تتم المعاملة؟

  • عندما يكون السعر أعلى من أو يساوي الحد الذي حددته.
  • عندما يتغير السعر.
  • عند انتهاء فترة التهدئة.
  • عند نجاح المحاكاة.

7. النتيجة

عندما ترى في سطر الأوامر:

EXECUTED: 19483921

هذا يعني:

  • تمت المبادلة بنجاح.
  • أنهى السكربت عمله.

8. معاملات هامة
الحد الأدنى (المدخل الثاني)

node app.js 0.1 220

حد أعلى = معاملات أقل ولكن بسعر تنفيذ أفضل.

المبلغ (المدخل الأول)

node app.js 0.05 200

مبلغ أقل = تأثير أقل على السعر (Price Impact) ومخاطرة أقل.

9. ما الذي يجب فهمه؟

  • هذا لا يضمن دائماً أفضل سعر في العالم.
  • لا يحمي من كل أنواع الهجمات الممكنة.
  • لكنه يقلل بشكل كبير من فرصة تعرضك لعمليات الـ "Front-run".

10. متى لا تستخدمه؟

  • إذا كنت لا تفهم كيف يعمل الانزلاق السعري (Slippage).
  • إذا لم يكن لديك رصيد كافٍ لتغطية الغاز.
  • عندما تكون الشبكة مزدحمة تماماً.

الخلاصة

  • تشغيل بأمر واحد.
  • يعمل تلقائياً.
  • يقوم بمبادلة "خفية" عبر Flashbots.

هذا الكود: لن يهزم بوتات MEV المحترفة في مواجهة مباشرة، ولن يحميك في كل سيناريو ممكن، ولا يعطي ميزة سحرية.

ولكن:
👉 لن تكون فريسة سهلة بعد الآن.

 

هذه الأداة هي مجرد قمة جبل الجليد. يمكن تطويرها للتحكيم (Arbitrage) أو التصفية أو نقل سيولة كبيرة بأمان.

تذكر القاعدة البسيطة: في "الغابة المظلمة" للبلوكشين، لا يفوز من يصرخ بصوت أعلى، بل من يعرف كيف يتسلل بهدوء.

تم إعداد المادة لـ أكاديمية EXMON. قم بالتجربة على الشبكة الرئيسية (Mainnet) بحذر ودائماً راقب إعدادات الانزلاق السعري الخاص بك!

Sying Yu

I am a blockchain developer specializing in building secure, scalable, and innovative decentralized solutions. My expertise covers smart contracts, payment systems, and integrating crypto with fiat to optimize financial workflows. I thrive on creating modern, efficient tools for the evolving digital economy....

شاركنا برأيك

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها *