[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-2-namudhaj-dhakira-makdas-takhzin-calldata":3},{"article":4,"author":54},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":34,"related_articles":35},"d9000000-0000-0000-0000-000000000102","a0000000-0000-0000-0000-000000000092","Deep EVM #2: نموذج الذاكرة — المكدس والذاكرة والتخزين وcalldata","deep-evm-2-namudhaj-dhakira-makdas-takhzin-calldata","غوص عميق في مواقع البيانات الأربعة لـ EVM — المكدس والذاكرة والتخزين وcalldata — تكلفتها وسلوكها وصيغة توسيع الذاكرة.","## مواقع البيانات الأربعة\n\nتحتوي EVM على أربعة مواقع مميزة للبيانات، لكل منها خصائص تكلفة ودورة حياة مختلفة:\n\n1. **المكدس** — مؤقت لكل استدعاء. مجاني للعمليات (3 غاز لـ PUSH\u002FDUP\u002FSWAP). عمق أقصى 1024. هذا هو \"سجل العمل\" الخاص بك.\n2. **الذاكرة** — مؤقتة لكل استدعاء. مصفوفة بايت خطية تتوسع عند الطلب. القراءة\u002Fالكتابة 3 غاز، لكن التوسيع يكلف بشكل تربيعي.\n3. **التخزين** — دائم عبر المعاملات. أزواج مفتاح-قيمة (32 بايت -> 32 بايت). الأغلى: 2100-22100 غاز لكل عملية.\n4. **Calldata** — للقراءة فقط، بيانات الإدخال المرسلة مع المعاملة. 16 غاز لكل بايت غير صفري، 4 لكل بايت صفري.\n\n## المكدس بالتفصيل\n\nالمكدس هو بنية LIFO (آخر ما يدخل أول ما يخرج) بعمق أقصى 1024 عنصر. كل عنصر بعرض 256 بت بالضبط. لا يمكنك دفع قيمة 8 بت — يتم توسيعها دائماً إلى 256 بت بأصفار بادئة.\n\nالمكدس خاص بسياق الاستدعاء الحالي. عندما يستدعي العقد A العقد B عبر CALL، يحصل B على مكدس جديد فارغ. عندما يعود B، يُهمل مكدسه ويستمر A بمكدسه الأصلي.\n\n## الذاكرة: التوسيع التربيعي\n\nالذاكرة عبارة عن مصفوفة بايت تبدأ فارغة وتتوسع في أجزاء من 32 بايت. يتم تهيئة كل ذاكرة جديدة بأصفار.\n\nتكلفة الذاكرة ليست خطية. صيغة الغاز لتوسيع الذاكرة هي:\n\n```\nتكلفة_الذاكرة(الحجم) = (الحجم² \u002F 512) + (3 × الحجم)\n```\n\nحيث الحجم بوحدات من 32 بايت. هذا يعني أن أول بضعة كيلوبايتات رخيصة، لكن تخصيص ميغابايتات يصبح باهظاً بشكل فلكي.\n\n```\n\u002F\u002F أمثلة على تكلفة الذاكرة:\n\u002F\u002F 32 بايت:    3 غاز\n\u002F\u002F 1 كيلوبايت:   98 غاز\n\u002F\u002F 10 كيلوبايت:  9,800 غاز\n\u002F\u002F 1 ميغابايت:  شيء ضخم جداً\n```\n\n### مؤشر الذاكرة الحرة\n\nيحتفظ Solidity بـ \"مؤشر الذاكرة الحرة\" في الموضع `0x40`. هذا يشير إلى البايت التالي غير المخصص في الذاكرة. يقوم المترجم بتحديثه عند تخصيص الذاكرة.\n\n```solidity\n\u002F\u002F ما يفعله Solidity خلف الكواليس:\nassembly {\n    let ptr := mload(0x40)        \u002F\u002F قراءة مؤشر الذاكرة الحرة\n    mstore(ptr, value)             \u002F\u002F كتابة في الذاكرة الحرة\n    mstore(0x40, add(ptr, 0x20))   \u002F\u002F تقدم المؤشر بـ 32 بايت\n}\n```\n\n## التخزين: أغلى موقع بيانات\n\nالتخزين هو خريطة مفتاح-قيمة حيث كل من المفتاح والقيمة بحجم 32 بايت. إنه المكان الوحيد الذي تستمر فيه البيانات بين المعاملات.\n\nتكاليف الغاز (بعد EIP-2929):\n- **SLOAD بارد:** 2100 غاز (أول قراءة في المعاملة)\n- **SLOAD دافئ:** 100 غاز (قراءات لاحقة)\n- **SSTORE (0 إلى غير صفري):** 22100 غاز (تخصيص فتحة جديدة)\n- **SSTORE (غير صفري إلى غير صفري):** 5000 غاز (تحديث)\n- **SSTORE (غير صفري إلى 0):** 5000 غاز - 4800 استرداد\n\n### تخطيط التخزين\n\niقوم Solidity بتخطيط متغيرات الحالة لفتحات تخزين بشكل حتمي:\n\n```solidity\ncontract Example {\n    uint256 public a;     \u002F\u002F فتحة 0\n    uint256 public b;     \u002F\u002F فتحة 1\n    mapping(address => uint256) public balances; \u002F\u002F فتحة 2 (أساس)\n}\n```\n\nللمصفوفات الديناميكية والتعيينات، يتم حساب الفتحة الفعلية باستخدام `keccak256`:\n\n```\n\u002F\u002F فتحة الرصيد لعنوان:\nslot = keccak256(abi.encode(address, 2))  \u002F\u002F keccak256(مفتاح ++ فتحة_التعيين)\n```\n\n## Calldata: بيانات الإدخال\n\nCalldata هي بيانات الإدخال الخام المرسلة مع المعاملة. إنها للقراءة فقط — لا يمكنك الكتابة إلى calldata.\n\nأكواد التشغيل:\n- **CALLDATALOAD(offset)** — تحميل 32 بايت من calldata بدءاً من الإزاحة\n- **CALLDATASIZE** — حجم calldata بالبايت\n- **CALLDATACOPY(destOffset, offset, length)** — نسخ calldata إلى الذاكرة\n\nCalldata أرخص من الذاكرة لتمرير البيانات لأنك تدفع فقط تكلفة الغاز الجوهري (16 غاز\u002Fبايت غير صفري) ولا تحتاج لنسخها إلى الذاكرة إلا عند الحاجة.\n\n## الأنماط العملية\n\n### تخزين مؤقت لقراءات التخزين\n\nأكثر نمط تحسين غاز شيوعاً: قراءة التخزين مرة واحدة وتخزين القيمة مؤقتاً في متغير ذاكرة.\n\n```solidity\n\u002F\u002F سيء: قراءتان من التخزين (2100 + 100 = 2200 غاز)\nfunction bad() external view returns (uint256) {\n    return myValue + myValue;\n}\n\n\u002F\u002F جيد: قراءة واحدة من التخزين (2100 غاز)\nfunction good() external view returns (uint256) {\n    uint256 cached = myValue;\n    return cached + cached;\n}\n```\n\n### calldata مقابل memory في معاملات الدوال\n\nللمعاملات الخارجية للقراءة فقط، استخدم `calldata` بدلاً من `memory`:\n\n```solidity\n\u002F\u002F أرخص: يقرأ مباشرة من calldata\nfunction process(uint256[] calldata data) external {\n    \u002F\u002F ...\n}\n\n\u002F\u002F أغلى: ينسخ calldata إلى الذاكرة\nfunction process(uint256[] memory data) external {\n    \u002F\u002F ...\n}\n```\n\n## الخلاصة\n\nفهم مواقع البيانات الأربعة لـ EVM هو أساسي لكتابة عقود ذكية فعالة من حيث الغاز. المكدس مجاني لكن محدود بعمق 16. الذاكرة رخيصة لكن تتوسع بشكل تربيعي. التخزين دائم لكن باهظ. Calldata للقراءة فقط لكنها الأرخص لبيانات الإدخال. اختيار الموقع الصحيح يحدد ما إذا كان عقدك يكلف $0.50 أو $50 للتنفيذ.","\u003Ch2 id=\"\">مواقع البيانات الأربعة\u003C\u002Fh2>\n\u003Cp>تحتوي EVM على أربعة مواقع مميزة للبيانات، لكل منها خصائص تكلفة ودورة حياة مختلفة:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>المكدس\u003C\u002Fstrong> — مؤقت لكل استدعاء. مجاني للعمليات (3 غاز لـ PUSH\u002FDUP\u002FSWAP). عمق أقصى 1024. هذا هو “سجل العمل” الخاص بك.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>الذاكرة\u003C\u002Fstrong> — مؤقتة لكل استدعاء. مصفوفة بايت خطية تتوسع عند الطلب. القراءة\u002Fالكتابة 3 غاز، لكن التوسيع يكلف بشكل تربيعي.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>التخزين\u003C\u002Fstrong> — دائم عبر المعاملات. أزواج مفتاح-قيمة (32 بايت -&gt; 32 بايت). الأغلى: 2100-22100 غاز لكل عملية.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Calldata\u003C\u002Fstrong> — للقراءة فقط، بيانات الإدخال المرسلة مع المعاملة. 16 غاز لكل بايت غير صفري، 4 لكل بايت صفري.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">المكدس بالتفصيل\u003C\u002Fh2>\n\u003Cp>المكدس هو بنية LIFO (آخر ما يدخل أول ما يخرج) بعمق أقصى 1024 عنصر. كل عنصر بعرض 256 بت بالضبط. لا يمكنك دفع قيمة 8 بت — يتم توسيعها دائماً إلى 256 بت بأصفار بادئة.\u003C\u002Fp>\n\u003Cp>المكدس خاص بسياق الاستدعاء الحالي. عندما يستدعي العقد A العقد B عبر CALL، يحصل B على مكدس جديد فارغ. عندما يعود B، يُهمل مكدسه ويستمر A بمكدسه الأصلي.\u003C\u002Fp>\n\u003Ch2 id=\"\">الذاكرة: التوسيع التربيعي\u003C\u002Fh2>\n\u003Cp>الذاكرة عبارة عن مصفوفة بايت تبدأ فارغة وتتوسع في أجزاء من 32 بايت. يتم تهيئة كل ذاكرة جديدة بأصفار.\u003C\u002Fp>\n\u003Cp>تكلفة الذاكرة ليست خطية. صيغة الغاز لتوسيع الذاكرة هي:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>تكلفة_الذاكرة(الحجم) = (الحجم² \u002F 512) + (3 × الحجم)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>حيث الحجم بوحدات من 32 بايت. هذا يعني أن أول بضعة كيلوبايتات رخيصة، لكن تخصيص ميغابايتات يصبح باهظاً بشكل فلكي.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F أمثلة على تكلفة الذاكرة:\n\u002F\u002F 32 بايت:    3 غاز\n\u002F\u002F 1 كيلوبايت:   98 غاز\n\u002F\u002F 10 كيلوبايت:  9,800 غاز\n\u002F\u002F 1 ميغابايت:  شيء ضخم جداً\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>مؤشر الذاكرة الحرة\u003C\u002Fh3>\n\u003Cp>يحتفظ Solidity بـ “مؤشر الذاكرة الحرة” في الموضع \u003Ccode>0x40\u003C\u002Fcode>. هذا يشير إلى البايت التالي غير المخصص في الذاكرة. يقوم المترجم بتحديثه عند تخصيص الذاكرة.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F ما يفعله Solidity خلف الكواليس:\nassembly {\n    let ptr := mload(0x40)        \u002F\u002F قراءة مؤشر الذاكرة الحرة\n    mstore(ptr, value)             \u002F\u002F كتابة في الذاكرة الحرة\n    mstore(0x40, add(ptr, 0x20))   \u002F\u002F تقدم المؤشر بـ 32 بايت\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">التخزين: أغلى موقع بيانات\u003C\u002Fh2>\n\u003Cp>التخزين هو خريطة مفتاح-قيمة حيث كل من المفتاح والقيمة بحجم 32 بايت. إنه المكان الوحيد الذي تستمر فيه البيانات بين المعاملات.\u003C\u002Fp>\n\u003Cp>تكاليف الغاز (بعد EIP-2929):\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>SLOAD بارد:\u003C\u002Fstrong> 2100 غاز (أول قراءة في المعاملة)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>SLOAD دافئ:\u003C\u002Fstrong> 100 غاز (قراءات لاحقة)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>SSTORE (0 إلى غير صفري):\u003C\u002Fstrong> 22100 غاز (تخصيص فتحة جديدة)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>SSTORE (غير صفري إلى غير صفري):\u003C\u002Fstrong> 5000 غاز (تحديث)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>SSTORE (غير صفري إلى 0):\u003C\u002Fstrong> 5000 غاز - 4800 استرداد\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>تخطيط التخزين\u003C\u002Fh3>\n\u003Cp>iقوم Solidity بتخطيط متغيرات الحالة لفتحات تخزين بشكل حتمي:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">contract Example {\n    uint256 public a;     \u002F\u002F فتحة 0\n    uint256 public b;     \u002F\u002F فتحة 1\n    mapping(address =&gt; uint256) public balances; \u002F\u002F فتحة 2 (أساس)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>للمصفوفات الديناميكية والتعيينات، يتم حساب الفتحة الفعلية باستخدام \u003Ccode>keccak256\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F فتحة الرصيد لعنوان:\nslot = keccak256(abi.encode(address, 2))  \u002F\u002F keccak256(مفتاح ++ فتحة_التعيين)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"calldata\">Calldata: بيانات الإدخال\u003C\u002Fh2>\n\u003Cp>Calldata هي بيانات الإدخال الخام المرسلة مع المعاملة. إنها للقراءة فقط — لا يمكنك الكتابة إلى calldata.\u003C\u002Fp>\n\u003Cp>أكواد التشغيل:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>CALLDATALOAD(offset)\u003C\u002Fstrong> — تحميل 32 بايت من calldata بدءاً من الإزاحة\u003C\u002Fli>\n\u003Cli>\u003Cstrong>CALLDATASIZE\u003C\u002Fstrong> — حجم calldata بالبايت\u003C\u002Fli>\n\u003Cli>\u003Cstrong>CALLDATACOPY(destOffset, offset, length)\u003C\u002Fstrong> — نسخ calldata إلى الذاكرة\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Calldata أرخص من الذاكرة لتمرير البيانات لأنك تدفع فقط تكلفة الغاز الجوهري (16 غاز\u002Fبايت غير صفري) ولا تحتاج لنسخها إلى الذاكرة إلا عند الحاجة.\u003C\u002Fp>\n\u003Ch2 id=\"\">الأنماط العملية\u003C\u002Fh2>\n\u003Ch3>تخزين مؤقت لقراءات التخزين\u003C\u002Fh3>\n\u003Cp>أكثر نمط تحسين غاز شيوعاً: قراءة التخزين مرة واحدة وتخزين القيمة مؤقتاً في متغير ذاكرة.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F سيء: قراءتان من التخزين (2100 + 100 = 2200 غاز)\nfunction bad() external view returns (uint256) {\n    return myValue + myValue;\n}\n\n\u002F\u002F جيد: قراءة واحدة من التخزين (2100 غاز)\nfunction good() external view returns (uint256) {\n    uint256 cached = myValue;\n    return cached + cached;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>calldata مقابل memory في معاملات الدوال\u003C\u002Fh3>\n\u003Cp>للمعاملات الخارجية للقراءة فقط، استخدم \u003Ccode>calldata\u003C\u002Fcode> بدلاً من \u003Ccode>memory\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F أرخص: يقرأ مباشرة من calldata\nfunction process(uint256[] calldata data) external {\n    \u002F\u002F ...\n}\n\n\u002F\u002F أغلى: ينسخ calldata إلى الذاكرة\nfunction process(uint256[] memory data) external {\n    \u002F\u002F ...\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">الخلاصة\u003C\u002Fh2>\n\u003Cp>فهم مواقع البيانات الأربعة لـ EVM هو أساسي لكتابة عقود ذكية فعالة من حيث الغاز. المكدس مجاني لكن محدود بعمق 16. الذاكرة رخيصة لكن تتوسع بشكل تربيعي. التخزين دائم لكن باهظ. Calldata للقراءة فقط لكنها الأرخص لبيانات الإدخال. اختيار الموقع الصحيح يحدد ما إذا كان عقدك يكلف $0.50 أو $50 للتنفيذ.\u003C\u002Fp>\n","ar","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:32.224924Z","غوص عميق في مواقع البيانات الأربعة لـ EVM — المكدس والذاكرة والتخزين وcalldata — تكلفتها وسلوكها وتحسين الغاز.","نموذج ذاكرة EVM",null,"index, follow",[21,26,30],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":31,"name":32,"slug":33,"created_at":25},"c0000000-0000-0000-0000-000000000014","Solidity","solidity","بلوكتشين",[36,42,48],{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":34,"published_at":41},"d0000000-0000-0000-0000-000000000617","طبقة التشغيل البيني لـ Ethereum: كيف تصبح 55+ سلسلة L2 سلسلة واحدة","tabaqat-altashghil-albaini-ethereum-55-l2-silsila-wahida","يملك Ethereum اكثر من 55 rollup من الطبقة الثانية، مما يجزئ السيولة وتجربة المستخدم. طبقة التشغيل البيني لـ Ethereum — الجمع بين الرسائل عبر الـ rollups والمتسلسلات المشتركة والـ based rollups — تهدف الى توحيدها في شبكة قابلة للتركيب واحدة.","2026-03-28T10:44:45.626845Z",{"id":43,"title":44,"slug":45,"excerpt":46,"locale":12,"category_name":34,"published_at":47},"d0000000-0000-0000-0000-000000000616","اثباتات ZK ما وراء الـ Rollups: استدلال الذكاء الاصطناعي القابل للتحقق على Ethereum","ithbatat-zk-ma-waraa-rollups-istidlal-dhakaa-istinaai-ethereum","اثباتات المعرفة الصفرية لم تعد مجرد اداة للتوسع. في 2026، يتيح zkML استدلال الذكاء الاصطناعي القابل للتحقق على السلسلة، وتنقل معالجات ZK المشتركة الحسابات الثقيلة خارج السلسلة مع التحقق على السلسلة، وانظمة الاثبات الجديدة مثل SP1 وJolt تجعل ذلك عمليا.","2026-03-28T10:44:45.621594Z",{"id":49,"title":50,"slug":51,"excerpt":52,"locale":12,"category_name":34,"published_at":53},"d0000000-0000-0000-0000-000000000593","EIP-7702 في الممارسة العملية: بناء تدفقات الحساب الذكي بعد Pectra","eip-7702-fi-almumaarasa-alamaliyya-binaa-tadaffuqat-alhisab-aldhaki-baad-pectra","يسمح EIP-7702 لأي EOA على Ethereum بالعمل مؤقتاً كعقد ذكي في معاملة واحدة. إليك كيفية تنفيذ المعاملات المجمّعة ورعاية الغاز والاسترداد الاجتماعي باستخدام البدائية الجديدة لتجريد الحساب.","2026-03-28T10:44:44.185251Z",{"id":13,"name":55,"slug":56,"bio":57,"photo_url":18,"linkedin":18,"role":58,"created_at":59,"updated_at":59},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]