[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-5-muqaddima-fi-yul-lughat-tajmie-sirriya-solidity":3},{"article":4,"author":58},{"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":38,"related_articles":39},"d9000000-0000-0000-0000-000000000105","a0000000-0000-0000-0000-000000000092","Deep EVM #5: مقدمة في Yul — لغة التجميع السرية لـ Solidity","deep-evm-5-muqaddima-fi-yul-lughat-tajmie-sirriya-solidity","تعلم Yul، لغة التجميع المضمنة في Solidity التي تمنحك الوصول المباشر لأكواد تشغيل EVM. الجملة النحوية، تدفق التحكم، والوصول إلى الذاكرة والتخزين.","## ما هي Yul؟\n\nYul هي لغة وسيطة يمكن تجميعها إلى بايتكود لعدة خلفيات مختلفة، بما في ذلك EVM. يمكنك استخدامها مباشرة داخل Solidity عبر كتل `assembly { }` أو كلغة مستقلة.\n\nلماذا Yul وليس Solidity العادية؟\n- **تحسين الغاز** — Yul يمنحك تحكماً دقيقاً في الكود المُولد\n- **عمليات منخفضة المستوى** — الوصول المباشر للذاكرة والتخزين وcalldata\n- **أنماط مستحيلة في Solidity** — مثل returndatasize كبديل رخيص لـ push 0\n\n## البنية الأساسية\n\nYul تبدو مثل Solidity مبسطة بدون أنواع (كل شيء uint256):\n\n```solidity\nassembly {\n    \u002F\u002F المتغيرات\n    let x := 42\n    let y := add(x, 1)  \u002F\u002F y = 43\n    \n    \u002F\u002F الشروط\n    if gt(x, 0) {\n        y := mul(x, 2)\n    }\n    \n    \u002F\u002F الحلقات\n    for { let i := 0 } lt(i, 10) { i := add(i, 1) } {\n        \u002F\u002F جسم الحلقة\n    }\n    \n    \u002F\u002F الدوال\n    function double(val) -> result {\n        result := mul(val, 2)\n    }\n}\n```\n\n## الوصول إلى الذاكرة\n\nفي Yul، تتعامل مع الذاكرة مباشرة باستخدام `mload` و`mstore`:\n\n```solidity\nassembly {\n    \u002F\u002F كتابة 32 بايت في الذاكرة عند الإزاحة 0x00\n    mstore(0x00, 0x1234)\n    \n    \u002F\u002F قراءة 32 بايت من الذاكرة عند الإزاحة 0x00\n    let val := mload(0x00)\n    \n    \u002F\u002F مؤشر الذاكرة الحرة\n    let ptr := mload(0x40)\n    mstore(ptr, someValue)\n    mstore(0x40, add(ptr, 0x20))  \u002F\u002F تقديم المؤشر\n}\n```\n\n## الوصول إلى التخزين\n\n```solidity\nassembly {\n    \u002F\u002F قراءة من فتحة التخزين 0\n    let val := sload(0)\n    \n    \u002F\u002F كتابة إلى فتحة التخزين 0\n    sstore(0, 42)\n    \n    \u002F\u002F حساب فتحة التعيين\n    mstore(0x00, key)\n    mstore(0x20, mappingSlot)\n    let slot := keccak256(0x00, 0x40)\n    let mappedValue := sload(slot)\n}\n```\n\n## التعامل مع Calldata\n\n```solidity\nassembly {\n    \u002F\u002F تحميل أول 4 بايت (محدد الدالة)\n    let selector := shr(224, calldataload(0))\n    \n    \u002F\u002F تحميل المعامل الأول (بعد المحدد)\n    let arg1 := calldataload(4)\n    \n    \u002F\u002F حجم calldata\n    let size := calldatasize()\n}\n```\n\n## أنماط تحسين الغاز في Yul\n\n### بديل PUSH0\n```solidity\nassembly {\n    \u002F\u002F بدلاً من PUSH1 0x00 (3 غاز + 1 بايت)\n    \u002F\u002F استخدم returndatasize() قبل أي استدعاء خارجي\n    let zero := returndatasize() \u002F\u002F 2 غاز\n}\n```\n\n### ترميز ABI يدوي\n```solidity\nassembly {\n    \u002F\u002F بدلاً من abi.encode(a, b)\n    mstore(0x00, a)\n    mstore(0x20, b)\n    \u002F\u002F البيانات المرمزة الآن في الذاكرة [0x00..0x40]\n}\n```\n\n### إرجاع مخصص\n```solidity\nassembly {\n    mstore(0x00, value)\n    return(0x00, 0x20)  \u002F\u002F إرجاع 32 بايت من الذاكرة\n}\n```\n\n## Yul كلغة مستقلة\n\nيمكنك كتابة عقود كاملة في Yul:\n\n```yul\nobject \"SimpleStore\" {\n    code {\n        \u002F\u002F كود المُنشئ: نسخ كود التشغيل وإعادته\n        datacopy(0, dataoffset(\"runtime\"), datasize(\"runtime\"))\n        return(0, datasize(\"runtime\"))\n    }\n    object \"runtime\" {\n        code {\n            \u002F\u002F محدد الدالة\n            switch shr(224, calldataload(0))\n            case 0x6d4ce63c \u002F* get() *\u002F {\n                mstore(0, sload(0))\n                return(0, 32)\n            }\n            case 0x60fe47b1 \u002F* set(uint256) *\u002F {\n                sstore(0, calldataload(4))\n            }\n            default {\n                revert(0, 0)\n            }\n        }\n    }\n}\n```\n\n## متى تستخدم Yul\n\nاستخدم Yul عندما:\n1. **تحسين الغاز ضروري** — المسارات الساخنة في عقود DeFi\n2. **عمليات منخفضة المستوى مطلوبة** — التعامل مع returndata، إنشاء عقود عبر CREATE2\n3. **Solidity لا تستطيع التعبير عما تريد** — أنماط ذاكرة مخصصة\n\nلا تستخدم Yul عندما:\n1. Solidity العادية تكفي — قابلية القراءة أهم\n2. الفريق لا يعرف EVM جيداً — Yul أسهل لكتابة الأخطاء\n3. التدقيق مطلوب — كود Yul أصعب في التدقيق\n\n## الخلاصة\n\nYul هي جسر بين Solidity عالية المستوى والبايتكود الخام. تمنحك تحكماً دقيقاً في الكود المُولد مع الحفاظ على قابلية القراءة أفضل من البايتكود المباشر. إتقان Yul هو خطوة أساسية نحو فهم EVM بعمق وكتابة عقود محسنة للغاز.","\u003Ch2 id=\"yul\">ما هي Yul؟\u003C\u002Fh2>\n\u003Cp>Yul هي لغة وسيطة يمكن تجميعها إلى بايتكود لعدة خلفيات مختلفة، بما في ذلك EVM. يمكنك استخدامها مباشرة داخل Solidity عبر كتل \u003Ccode>assembly { }\u003C\u002Fcode> أو كلغة مستقلة.\u003C\u002Fp>\n\u003Cp>لماذا Yul وليس Solidity العادية؟\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>تحسين الغاز\u003C\u002Fstrong> — Yul يمنحك تحكماً دقيقاً في الكود المُولد\u003C\u002Fli>\n\u003Cli>\u003Cstrong>عمليات منخفضة المستوى\u003C\u002Fstrong> — الوصول المباشر للذاكرة والتخزين وcalldata\u003C\u002Fli>\n\u003Cli>\u003Cstrong>أنماط مستحيلة في Solidity\u003C\u002Fstrong> — مثل returndatasize كبديل رخيص لـ push 0\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"\">البنية الأساسية\u003C\u002Fh2>\n\u003Cp>Yul تبدو مثل Solidity مبسطة بدون أنواع (كل شيء uint256):\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">assembly {\n    \u002F\u002F المتغيرات\n    let x := 42\n    let y := add(x, 1)  \u002F\u002F y = 43\n    \n    \u002F\u002F الشروط\n    if gt(x, 0) {\n        y := mul(x, 2)\n    }\n    \n    \u002F\u002F الحلقات\n    for { let i := 0 } lt(i, 10) { i := add(i, 1) } {\n        \u002F\u002F جسم الحلقة\n    }\n    \n    \u002F\u002F الدوال\n    function double(val) -&gt; result {\n        result := mul(val, 2)\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">الوصول إلى الذاكرة\u003C\u002Fh2>\n\u003Cp>في Yul، تتعامل مع الذاكرة مباشرة باستخدام \u003Ccode>mload\u003C\u002Fcode> و\u003Ccode>mstore\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">assembly {\n    \u002F\u002F كتابة 32 بايت في الذاكرة عند الإزاحة 0x00\n    mstore(0x00, 0x1234)\n    \n    \u002F\u002F قراءة 32 بايت من الذاكرة عند الإزاحة 0x00\n    let val := mload(0x00)\n    \n    \u002F\u002F مؤشر الذاكرة الحرة\n    let ptr := mload(0x40)\n    mstore(ptr, someValue)\n    mstore(0x40, add(ptr, 0x20))  \u002F\u002F تقديم المؤشر\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">الوصول إلى التخزين\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-solidity\">assembly {\n    \u002F\u002F قراءة من فتحة التخزين 0\n    let val := sload(0)\n    \n    \u002F\u002F كتابة إلى فتحة التخزين 0\n    sstore(0, 42)\n    \n    \u002F\u002F حساب فتحة التعيين\n    mstore(0x00, key)\n    mstore(0x20, mappingSlot)\n    let slot := keccak256(0x00, 0x40)\n    let mappedValue := sload(slot)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"calldata\">التعامل مع Calldata\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-solidity\">assembly {\n    \u002F\u002F تحميل أول 4 بايت (محدد الدالة)\n    let selector := shr(224, calldataload(0))\n    \n    \u002F\u002F تحميل المعامل الأول (بعد المحدد)\n    let arg1 := calldataload(4)\n    \n    \u002F\u002F حجم calldata\n    let size := calldatasize()\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"yul\">أنماط تحسين الغاز في Yul\u003C\u002Fh2>\n\u003Ch3>بديل PUSH0\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-solidity\">assembly {\n    \u002F\u002F بدلاً من PUSH1 0x00 (3 غاز + 1 بايت)\n    \u002F\u002F استخدم returndatasize() قبل أي استدعاء خارجي\n    let zero := returndatasize() \u002F\u002F 2 غاز\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>ترميز ABI يدوي\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-solidity\">assembly {\n    \u002F\u002F بدلاً من abi.encode(a, b)\n    mstore(0x00, a)\n    mstore(0x20, b)\n    \u002F\u002F البيانات المرمزة الآن في الذاكرة [0x00..0x40]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>إرجاع مخصص\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-solidity\">assembly {\n    mstore(0x00, value)\n    return(0x00, 0x20)  \u002F\u002F إرجاع 32 بايت من الذاكرة\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"yul\">Yul كلغة مستقلة\u003C\u002Fh2>\n\u003Cp>يمكنك كتابة عقود كاملة في Yul:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-yul\">object \"SimpleStore\" {\n    code {\n        \u002F\u002F كود المُنشئ: نسخ كود التشغيل وإعادته\n        datacopy(0, dataoffset(\"runtime\"), datasize(\"runtime\"))\n        return(0, datasize(\"runtime\"))\n    }\n    object \"runtime\" {\n        code {\n            \u002F\u002F محدد الدالة\n            switch shr(224, calldataload(0))\n            case 0x6d4ce63c \u002F* get() *\u002F {\n                mstore(0, sload(0))\n                return(0, 32)\n            }\n            case 0x60fe47b1 \u002F* set(uint256) *\u002F {\n                sstore(0, calldataload(4))\n            }\n            default {\n                revert(0, 0)\n            }\n        }\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"yul\">متى تستخدم Yul\u003C\u002Fh2>\n\u003Cp>استخدم Yul عندما:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>تحسين الغاز ضروري\u003C\u002Fstrong> — المسارات الساخنة في عقود DeFi\u003C\u002Fli>\n\u003Cli>\u003Cstrong>عمليات منخفضة المستوى مطلوبة\u003C\u002Fstrong> — التعامل مع returndata، إنشاء عقود عبر CREATE2\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Solidity لا تستطيع التعبير عما تريد\u003C\u002Fstrong> — أنماط ذاكرة مخصصة\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>لا تستخدم Yul عندما:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Solidity العادية تكفي — قابلية القراءة أهم\u003C\u002Fli>\n\u003Cli>الفريق لا يعرف EVM جيداً — Yul أسهل لكتابة الأخطاء\u003C\u002Fli>\n\u003Cli>التدقيق مطلوب — كود Yul أصعب في التدقيق\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">الخلاصة\u003C\u002Fh2>\n\u003Cp>Yul هي جسر بين Solidity عالية المستوى والبايتكود الخام. تمنحك تحكماً دقيقاً في الكود المُولد مع الحفاظ على قابلية القراءة أفضل من البايتكود المباشر. إتقان Yul هو خطوة أساسية نحو فهم EVM بعمق وكتابة عقود محسنة للغاز.\u003C\u002Fp>\n","ar","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:32.244086Z","تعلم Yul لغة التجميع المضمنة في Solidity: الجملة النحوية والذاكرة والتخزين وأنماط تحسين الغاز.","Yul EVM تجميع",null,"index, follow",[21,26,30,34],{"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",{"id":35,"name":36,"slug":37,"created_at":25},"c0000000-0000-0000-0000-000000000018","Yul","yul","بلوكتشين",[40,46,52],{"id":41,"title":42,"slug":43,"excerpt":44,"locale":12,"category_name":38,"published_at":45},"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":47,"title":48,"slug":49,"excerpt":50,"locale":12,"category_name":38,"published_at":51},"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":53,"title":54,"slug":55,"excerpt":56,"locale":12,"category_name":38,"published_at":57},"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":59,"slug":60,"bio":61,"photo_url":18,"linkedin":18,"role":62,"created_at":63,"updated_at":63},"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"]