# فهم EIP-7702 وتطبيقه

> لنفترض أنك تحاول تنفيذ معاملة ذرّية معقدة شاملة في خطوة واحدة تتطلب مبادلة الرموز، وإضافة السيولة، وتخزين المكافآت. لكن محفظة Ethereum العادية لديك، أي حساب EOA، لا تستطيع تنفيذ معاملات مجمّعة.

بقلم Shodipo Ayomide، نُشرت في 27 سبتمبر 2025. نسخة الويب: https://blog.shodipoayomide.com/ar/understanding-and-implementing-eip-7702

![فهم EIP-7702 وتطبيقه](https://blog.shodipoayomide.com/banners/understanding-and-implementing-eip-7702.png)

لنفترض أنك تحاول تنفيذ معاملة ذرّية معقدة شاملة في خطوة واحدة تتطلب مبادلة الرموز، وإضافة السيولة، وتخزين المكافآت (staking). لكن محفظة Ethereum العادية لديك، أي حساب EOA، لا تستطيع تنفيذ معاملات مجمّعة. لذا ستحتاج إلى توقيع ثلاث معاملات منفصلة، ودفع الغاز ثلاث مرات، وهذا أمر مرفوض تمامًا، ثم الدعاء ألا تحاصرك روبوتات MEV بهجوم الساندويتش بين الخطوات.

هذا أحد النقاشات الساخنة في منظومة `EVM` مؤخرًا، كيف بالضبط نمنح المحافظ العادية قدرات خارقة دون أن نكسر كل شيء في الوقت نفسه؟

خرج من هذا التحدي اقتراحان من `EIPs`، هما `EIP-3074` ثم `EIP-7702` لاحقًا. يسعى كلاهما إلى سد الفجوة بين `EOA` البسيط و `smart contract accounts`، لكنهما يتبعان نهجين مختلفين في تفويض الصلاحية. أحدهما يقدم صلاحية دائمة قد تسوء فيها الأمور كثيرًا وتُستنزف محافظك. والآخر يمكن أن يمنحك التفويض الدائم والتفويض المؤقت معًا، وقد يختفي التفويض المؤقت لحظة تنفيذ معاملتك على السلسلة.

لنتحدث عن سبب أهمية هذا الفرق، وكيف ربما أنقذ اقتراح Vitalik شبكة Ethereum من كابوس أمني محتمل.

## EIP-2718 - غلاف المعاملات ذات الأنواع

قبل أن ندخل في موضوع التفويض، هناك جزء مهم من البنية التحتية يجعل كل هذا ممكنًا، وهو `EIP-2718`. فكّر فيه على أنه نظام حاويات الشحن الخاص بالمعاملات في Ethereum.

```typescript
// before eip-2718 all transactions looked the same
const legacyTx = rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s]);

// after eip-2718 transactions can now be typed
const typedTx = TransactionType || TransactionPayload;
```

يقدّم `EIP-2718` مفهوم `Typed Transaction Envelopes`، حيث تكون `TransactionType || TransactionPayload` معاملة صالحة. يحدد `TransactionType` صيغة المعاملة، بينما يحتوي `Payload` على محتويات المعاملة. والآن، يعني نظام التغليف هذا أننا نستطيع تقديم سلوكيات جديدة كليًا للمعاملات دون كسر الوظائف الموجودة.

وبإدخال نوع معاملة مغلّف، لا نحتاج إلا إلى ضمان التوافق مع المعاملات الموجودة، ومن ثم لا يتبقى لنا إلا حل مشكلة أبسط بكثير، وهي ضمان عدم وجود تعارض في الترقيم بين `TransactionTypes`. لذا عندما احتاج `EIP-7702` إلى تقديم آلية التفويض المؤقت الخاصة به، أمكنه ببساطة أن يعرّف نوع معاملة جديدًا، على سبيل المثال `0x04`، دون أن يتطلب أي تغييرات في `EVM` نفسه.

## EIP-3074 - نهج التفويض الدائم

اتخذ [EIP-3074](https://eips.ethereum.org/EIPS/eip-3074) نهجًا جريئًا في التفويض، إذ منح `EOAs` القدرة على تفويض الصلاحية بشكل دائم إلى العقود الذكية باستخدام اثنين من `opcodes` الجديدة في `EVM` - `AUTH` و `AUTHCALL`.

### كيف يعمل AUTH و AUTHCALL

الآلية بسيطة ومباشرة

```solidity
// user signs an auth message
bytes32 commit = keccak256(abi.encode(invokerAddress, batchActions));
bytes memory signature = signMessage(userPrivateKey, commit);

// invoker contract calls AUTH opcode
AUTH(commit, signature.v, signature.r, signature.s);
// This sets the 'authorized' context variable to user's address

// now invoker can make calls as the user
AUTHCALL(gasLimit, targetContract, 0, 0, calldata, calldataLength, 0, 0);
```

يأخذ `AUTH` أربع وسائط، `commit` و `yParity` الخاص بالتوقيع و `r` و `s`، وإذا كان التوقيع صالحًا وكان عنوان الموقّع مساويًا لصاحب الصلاحية، تُضبط قيمة متغير السياق authorized على صاحب الصلاحية ذاك. ثم يسمح `AUTHCALL` لعقد الاستدعاء (invoker) المخوَّل بإرسال المعاملات، مع ضبط `CALLER` على العنوان المخوَّل بدلًا من عنوان عقد الاستدعاء.

والآن، تخيّل عقد استدعاء يستطيع التعامل مع المعاملات المجمّعة

```solidity
contract BatchInvoker {
    struct BatchCall {
        address target;
        bytes data;
        uint256 value;
    }
    
    function executeBatch(
        BatchCall[] calldata calls,
        bytes32 commit,
        uint8 v, bytes32 r, bytes32 s
    ) external {
        // authorize the user
        AUTH(commit, v, r, s);
        
        // Execute all calls as the user
        for (uint i = 0; i < calls.length; i++) {
            AUTHCALL(
                gasleft(),
                calls[i].target,
                calls[i].value,
                0, // valueExt (must be 0 for now)
                // ... calldata parameters
            );
        }
    }
}
```

بقدر ما يبدو هذا مثيرًا، فقد أثار هذان الـ `opcodes` عددًا من المخاوف الأمنية لدى مجتمع `EVM`. فمتغير السياق `authorized` يستمر طوال إطار تنفيذ واحد للعقد، لكنه لا يُمرَّر عبر أي استدعاءات بما فيها `DELEGATECALL`. وهذا يعني في الأساس أن التخويل يبقى فعّالًا طوال نطاق المعاملة بأكملها.

المشكلة الحقيقية ليست في الطبيعة المؤقتة داخل المعاملة، بل فيما يحدث عندما تكون لديك عقود استدعاء واسعة الاستخدام. فإذا كان الجميع سيستخدمون الحسابات الذكية في النهاية، فقد يصبح `AUTH` و `AUTHCALL` من الـ `opcodes` عبئًا تقنيًا ضخمًا ويضيفان تعقيدًا إلى `EVM` نفسه.

ماذا يحدث عندما يحتوي عقد استدعاء شائع مثل العقد أعلاه على خلل؟ فجأة، يصبح كل مستخدم سبق أن خوّل ذلك العقد معرّضًا للخطر على الأرجح. تحديث خبيث واحد، أو حالة حدّية واحدة فاتتك، أو تجاوز عدد صحيح واحد، وانتهى الأمر، يبدأ استنزاف جماعي.

أدركت منظومة `EVM` أن هذا خلق ديناميكية غريبة. فنموذج الأمان في `EIP-3074` يعتمد بشدة على عقد الاستدعاء. وبما أن مستخدمين كثيرين قد يعتمدون على منطق عقد الاستدعاء نفسه، فإن ثغرة أو استغلالًا في عقد استدعاء واحد قد يعرّض أصول أو صلاحيات كثير من المستخدمين للخطر دفعة واحدة، ولهذا سُحب `EIP-3074`.

## EIP-7702 - حل التفويض المرن

والآن، فإن [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) الذي اقترحه Vitalik في مايو 2024 وصل إلى `mainnet` عبر `pectra upgrade` في مايو 2025، وهو يقدّم نهجًا جديدًا مبسّطًا يسمح لـ `EOAs` بأن تعمل مؤقتًا مثل العقود الذكية طوال مدة معاملة واحدة، وهذا أمر كبير!

بدلًا من `opcodes` جديدة، يستفيد `EIP-7702` من نظام تغليف المعاملات في `EIP-2718's` لتقديم نوع معاملة جديد

```typescript
interface EIP7702Transaction {
    chainId: number;
    nonce: number;
    maxPriorityFeePerGas: bigint;
    maxFeePerGas: bigint;
    gasLimit: bigint;
    to: string;
    value: bigint;
    data: Uint8Array;
    accessList: AccessList;
    authorizationList: Authorization[];
}

interface Authorization {
    chainId: number;
    address: string;  // the address of the contract code to delegate to
    nonce: number;
    yParity: 0 | 1;
    r: Uint8Array;
    s: Uint8Array;
}
```

لكل كائن تخويل، يُكتب مؤشر تفويض `(0xef0100 || address)` في شيفرة الحساب المانح للتخويل. ويجب على جميع العمليات التي تنفّذ الشيفرة أن تحمّل الشيفرة التي يشير إليها التفويض وتنفذها.

### كيف يعمل استمرار التفويض فعليًا
هذا هو الموضع الذي يرتبك فيه كثير من الناس. لقد تطوّر `EIP-7702` منذ مسودته الأصلية. ففي البداية، صُمم الاقتراح ليجعل `EOAs` ذكية مؤقتًا لمعاملة واحدة فقط. لكن النسخة النهائية تمنحك التحكم في المدة التي يستمر فيها التفويض.

```javascript
function processEIP7702Transaction(tx) {
    // verify all auth signatures
    for (const auth of tx.authorizationList) {
        const signer = recoverSigner(auth);
        if (signer !== getAddressFromAuth(auth)) {
            throw new Error("Invalid authorization");
        }
    }
    
    // set delegation pointers (these persist after transaction)
    for (const auth of tx.authorizationList) {
        const eoaAddress = getAddressFromAuth(auth);
        
        // set delegation pointer - 0xef0100 || contract_address
        const delegationPointer = concat(['0xef0100', auth.address]);
        setCode(eoaAddress, delegationPointer);
        
        // nowm this delegation PERSISTS unless explicitly cleared
    }
    
    // execute the transaction normally
    executeTransaction(tx);
    
    // no auto cleanup, delegation stays active
}
```

**ملاحظة:** إذا فشل تنفيذ معاملة `7702`، فإن مؤشرات التفويض التي عولجت لا يُتراجع عنها، وتبقى قائمة ما لم تُمسح صراحةً بضبط عنوان التفويض على `0x0` في معاملة `7702` لاحقة.

هذا يعني أن لديك ثلاثة أنماط للتفويض:

- التفويض الدائم: يضبط هذا النمط التفويض ويواصل استخدامه عبر معاملات متعددة
- التفويض المؤقت: يضبط هذا النمط التفويض لحالات استخدام محددة مثل التفويض إلى `Batching Contract` ليوم واحد، والتفويض نفسه دائم حتى يمسحه المستخدم.

### الخياران المؤقت والدائم معًا

الجميل في `EIP-7702` أنه يمنحك حرية الاختيار. هل تريد تفويضًا مؤقتًا لمعاملة معقدة لمرة واحدة؟ يمكنك ذلك. هل تريد ترقية `EOA` الخاص بك بشكل دائم ليعمل مثل محفظة عقد ذكي؟ يمكنك ذلك أيضًا.

للتفويض المؤقت، إليك مثالًا

```typescript
// one off delegation
const tempDelegationTx = {
    type: 0x04,
    authorizationList: [{
        address: batchExecutorContract,
        // ... auth details
    }],
    to: userAddress,
    data: encodeBatchCall([
        // execute your complex operation
        swapTokens(),
        addLiquidity(), 
        stakeRewards(),
    ])
};
```
وللتفويض الدائم، إليك مثالًا

```typescript
// upgrade EOA to smart wallet
const persistentDelegationTx = {
    type: 0x04,
    authorizationList: [{
        address: smartWalletImplementation,
        // ... auth details  
    }],
    to: userAddress,
    data: encodeCall("initializeSmartFeatures", [])
    // this delegation persists for future txns
};

// later txns can now use smart wallet features
const futureTransaction = {
    to: userAddress, // your EOA will now execute smart wallet code
    data: encodeCall("batchExecute", [multipleOperations])
    // no new auth needed
};
```

### لماذا يُعدّ 7702 أكثر أمانًا

الفرق الجوهري بين `EIP-3074` و `EIP-7702` ليس مجرد مؤقت مقابل دائم، بل يتعلق بتوزيع المخاطر والتحكم. يُنشئ `EIP-3074` نقطة فشل مشتركة قد تؤثر فيها مشكلة عقد واحد شائع في آلاف المستخدمين. أما `EIP-7702` فيعزل كل معاملة، لذا لا يمكن للأخطاء أن تؤثر إلا في تلك المعاملة بعينها. و `EIP-7702` متوافق تمامًا مع `ERC-4337` الموجود، ولا يتطلب أي `opcodes` جديدة. وهذا يعني في الأساس أن المحافظ تستطيع تبنّيه تدريجيًا دون كسر أي أنظمة قائمة.

الفكرة الحاسمة هي أن `wallets`، وليس `dApps`، هي التي تدير التفويضات. لذا فإن الاتفاق العام هو السماح للمحافظ وحدها بإدارة التفويضات، وهذا يعني:

- لا تستطيع تطبيقات dApps التحكم في تفويضك مباشرة
- يطبّق مزودو المحافظ منطق تفويض مُدقَّقًا ومُراجَعًا
- تتوزع المخاطر على تطبيقات كثيرة بدلًا من أن تتركز في عدد قليل من عقود الاستدعاء الشائعة

## ما يحتاج المطورون إلى معرفته

إذا كنت تبني تطبيقًا سيدعم `EIP-7702`، فهناك بعض الأمور التقنية التي يجب ملاحظتها

1. **تغييرات في بناء المعاملات**
يجب أن يتعامل منطق بناء المعاملات لديك مع قوائم التخويل

```typescript
// old: simple EOA transaction
const tx = {
    to: contractAddress,
    data: encodedCall,
    // ... standard fields
};

// new way with eip-7702 delegation
const tx = {
    type: 0x04,
    to: userAddress, // calling user's own address
    data: encodeBatchCall([
        contract.interface.encodeFunctionData("swap", [tokenA, tokenB, amount]),
        contract.interface.encodeFunctionData("addLiquidity", [lpTokens]),
        contract.interface.encodeFunctionData("stake", [lpAmount])
    ]),
    authorizationList: [{
        address: batchExecutorImplementation,
        // ... authorization signature
    }],
    // ... standard fields
};
```

2. **تعقيد تقدير الغاز**
إذا قرر حساب EOA إلغاء تحكم العقد الذكي، فيجب إرسال معاملة `7702` أخرى لإعادة ضبط التفويض على `0x0`. وهذا يعني أن تقدير الغاز لديك يجب أن يأخذ في الحسبان

- التحقق من توقيع التخويل
- إعداد مؤشر الشيفرة
- التنفيذ الفعلي
- تكلفة التنظيف الإضافية

3. **دعم توقيعات العقود الذكية**
يتيح `EIP-7702` التحقق من التوقيعات وفق `EIP-1271` لحسابات `EOAs`. وهذا يعني أن `EOA` **المُرقّى** الخاص بك يستطيع توقيع الرسائل باستخدام طرق بديلة مثل `passkeys`، مع الحفاظ على التوافق مع الإصدارات السابقة.

```solidity
// your EOA can now implement smart signature verification
function isValidSignature(bytes32 hash, bytes signature) external view returns (bytes4) {
    // can verify passkey signatures, multisig, etc.
    if (verifyPasskeySignature(hash, signature)) {
        return 0x1626ba7e; // EIP-1271 magic value
    }
    return 0xffffffff;
}
```

## روابط أساسية

- [EIP-2718: غلاف المعاملات ذات الأنواع](https://eips.ethereum.org/EIPS/eip-2718) - نظام تغليف المعاملات التأسيسي
- [EIP-3074: الـ opcodes المسمّاة AUTH و AUTHCALL](https://eips.ethereum.org/EIPS/eip-3074) - اقتراح التفويض الدائم
- [EIP-7702: ضبط شيفرة حساب EOA لمعاملة واحدة](https://eips.ethereum.org/EIPS/eip-7702) - اقتراح التفويض المؤقت
- [نقاش Ethereum Magicians](https://ethereum-magicians.org/t/eip-set-eoa-account-code-for-one-transaction/19923) - نقاش المجتمع حول EIP-7702
- [خارطة طريق Vitalik لتجريد الحسابات](https://ethereum-magicians.org/t/eip-set-eoa-account-code-for-one-transaction/19923)
