[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-9-tamhid-lughat-huff-makro-alamat-akwad-tashghil-kham":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-000000000109","a0000000-0000-0000-0000-000000000092","Deep EVM #9: تمهيد لغة Huff — الماكرو والعلامات وأكواد التشغيل الخام","deep-evm-9-tamhid-lughat-huff-makro-alamat-akwad-tashghil-kham","مقدمة عملية في Huff، لغة تجميع EVM منخفضة المستوى التي تمنحك تحكماً مباشراً في كل كود تشغيل وكل بايت من البايتكود وكل وحدة غاز.","## لماذا توجد Huff\n\nSolidity تجريد رائع — حتى لا يكون كذلك. عندما تحتاج لعقد يتسع في 100 بايت من بايتكود التشغيل، أو يرسل الدوال في O(1) بجدول قفز محزوم، أو يوفر 200 غاز في مسار ساخن يُنفذ ملايين المرات يومياً، تحتاج شيئاً أقرب للمعدن. هذا الشيء هو **Huff**.\n\nHuff هي لغة تجميع EVM منخفضة المستوى مع نظام ماكرو بسيط مُلصق فوقها. لا تحتوي على متغيرات أو أنواع أو مترجم يحسّن خلف ظهرك. ما تكتبه هو ما ينتهي على السلسلة — كود تشغيل بكود تشغيل.\n\n## تثبيت Huff\n\nالمترجم القياسي هو `huffc`، مكتوب بـ Rust:\n\n```bash\ncurl -L get.huff.sh | bash\nhuffup\nhuffc --version\n```\n\n## عالم مرحباً: عقد بسيط\n\nلنكتب عقداً يُرجع الكلمة 32 بايت `0x01` لأي استدعاء:\n\n```huff\n#define macro MAIN() = takes(0) returns(0) {\n    0x01            \u002F\u002F [0x01]\n    0x00            \u002F\u002F [0x00, 0x01]\n    mstore          \u002F\u002F []          — memory[0x00..0x20] = 0x01\n    0x20            \u002F\u002F [0x20]\n    0x00            \u002F\u002F [0x00, 0x20]\n    return          \u002F\u002F توقف — إرجاع memory[0x00..0x20]\n}\n```\n\nترجمة:\n\n```bash\nhuffc src\u002FHelloWorld.huff -r\n```\n\nالعلم `-r` يُخرج بايتكود التشغيل. سترى شيئاً مثل `600160005260206000f3` — 10 بايت. عقد Solidity يُرجع `1` يترجم إلى 200+ بايت تقريباً لأن solc يُصدر مرسل دوال كامل وتجزئة البيانات الوصفية وإعداد مؤشر الذاكرة الحرة ومرمز ABI.\n\n## الماكرو مقابل الدوال\n\nHuff لديها نوعان لإعادة استخدام الكود: **الماكرو** و**الدوال**.\n\n### الماكرو (`#define macro`)\n\nيتم تضمين الماكرو في كل موقع استدعاء. لا حمل JUMP إضافي، لا غاز إضافي — المترجم ينسخ أكواد التشغيل حرفياً في المستدعي. هذا هو الخيار الافتراضي والمفضل للكود الحرج من حيث الغاز.\n\n```huff\n#define macro REQUIRE_NOT_ZERO() = takes(1) returns(0) {\n    \u002F\u002F takes: [value]\n    continue        \u002F\u002F [continue_dest, value]\n    jumpi           \u002F\u002F []  — قفز إذا value != 0\n    0x00 0x00 revert\n    continue:\n}\n```\n\n### الدوال (`#define fn`)\n\nالدوال تولد زوج JUMP\u002FJUMPDEST فعلي. توفر حجم البايتكود على حساب ~22 غاز إضافي لكل استدعاء. استخدمها فقط عندما يكون حجم البايتكود أهم من الغاز.\n\n## العلامات ووجهات القفز\n\nالعلامات في Huff هي مواقع JUMPDEST مسماة. يحلها المترجم إلى إزاحات بايتكود محددة في وقت الترجمة.\n\n```huff\n#define macro LOOP_EXAMPLE() = takes(1) returns(1) {\n    \u002F\u002F takes: [n]\n    0x00                \u002F\u002F [acc, n]\n    loop:\n        dup2            \u002F\u002F [n, acc, n]\n        iszero          \u002F\u002F [n==0?, acc, n]\n        done jumpi      \u002F\u002F [acc, n]\n        swap1           \u002F\u002F [n, acc]\n        0x01 swap1 sub  \u002F\u002F [n-1, acc]\n        swap1           \u002F\u002F [acc, n-1]\n        0x01 add        \u002F\u002F [acc+1, n-1]\n        loop jump\n    done:\n        swap1 pop       \u002F\u002F [acc]\n}\n```\n\n## takes() وreturns()\n\nتوصيفات `takes(n)` و`returns(m)` على الماكرو والدوال هي توثيق وتلميحات للمترجم. تخبر القارئ — ومدقق المكدس في مترجم Huff — عن عدد عناصر المكدس التي يتوقع الكتلة استهلاكها وإنتاجها.\n\n## المقارنة: Huff مقابل بايتكود Solidity\n\nلنأخذ دالة عرض بسيطة `getValue()` تُرجع فتحة تخزين:\n\n**Solidity:**\n```solidity\nfunction getValue() external view returns (uint256) {\n    return value;\n}\n```\n\nsolc يولد ~40 بايت للمرسل + ترميز ABI.\n\n**مكافئ Huff:**\n```huff\n#define function getValue() view returns (uint256)\n\n#define macro GET_VALUE() = takes(0) returns(0) {\n    [VALUE_SLOT]    \u002F\u002F [slot]\n    sload           \u002F\u002F [value]\n    0x00 mstore     \u002F\u002F []  — تخزين في الذاكرة\n    0x20 0x00 return\n}\n```\n\nنسخة Huff هي 12 بايت من البايتكود للجسم. بدون حمل ترميز ABI أو مؤشر الذاكرة الحرة أو تجزئة البيانات الوصفية.\n\n## الثوابت وفتحات التخزين\n\nثوابت Huff هي قيم وقت الترجمة يتم تضمينها كتعليمات PUSH:\n\n```huff\n#define constant VALUE_SLOT = 0x00\n#define constant OWNER_SLOT = 0x01\n#define constant MAX_UINT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n```\n\nالاستخدام: `[VALUE_SLOT]` يدفع `0x00`. الثوابت تحسن القراءة بدون تكلفة غاز — هي بنيوية بحتة.\n\n## التضمينات وبنية المشروع\n\nمشاريع Huff الحقيقية تقسم الكود عبر ملفات متعددة:\n\n```huff\n\u002F\u002F src\u002FMain.huff\n#include \".\u002Futils\u002FSafeMath.huff\"\n#include \".\u002Finterfaces\u002FIERC20.huff\"\n#include \".\u002FDispatcher.huff\"\n\n#define macro MAIN() = takes(0) returns(0) {\n    DISPATCHER()\n}\n```\n\n## متى تستخدم Huff\n\nHuff ليست لغة عامة الأغراض. استخدمها عندما:\n\n1. **الغاز هو القيد الرئيسي** — عقود MEV حيث 100 غاز تحدد الربحية\n2. **حجم البايتكود مهم** — عقود مُنشأة بواسطة عقود أخرى (مصانع CREATE2)\n3. **تحتاج إرسال مخصص** — جداول القفز، محددات محزومة بالبتات\n4. **تتعلم EVM** — لا شيء يعلم EVM أفضل من كتابة أكواد تشغيل خام\n\n## الملخص\n\nHuff تمنحك خطاً مباشراً إلى بايتكود EVM مع تجريد كافٍ للبقاء عاقلاً. الماكرو تضمن الكود لإعادة استخدام بدون حمل. العلامات تتعامل مع حساب إزاحات القفز. توصيفات `takes`\u002F`returns` تكتشف أخطاء المكدس مبكراً.","\u003Ch2 id=\"huff\">لماذا توجد Huff\u003C\u002Fh2>\n\u003Cp>Solidity تجريد رائع — حتى لا يكون كذلك. عندما تحتاج لعقد يتسع في 100 بايت من بايتكود التشغيل، أو يرسل الدوال في O(1) بجدول قفز محزوم، أو يوفر 200 غاز في مسار ساخن يُنفذ ملايين المرات يومياً، تحتاج شيئاً أقرب للمعدن. هذا الشيء هو \u003Cstrong>Huff\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Cp>Huff هي لغة تجميع EVM منخفضة المستوى مع نظام ماكرو بسيط مُلصق فوقها. لا تحتوي على متغيرات أو أنواع أو مترجم يحسّن خلف ظهرك. ما تكتبه هو ما ينتهي على السلسلة — كود تشغيل بكود تشغيل.\u003C\u002Fp>\n\u003Ch2 id=\"huff\">تثبيت Huff\u003C\u002Fh2>\n\u003Cp>المترجم القياسي هو \u003Ccode>huffc\u003C\u002Fcode>، مكتوب بـ Rust:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">curl -L get.huff.sh | bash\nhuffup\nhuffc --version\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">عالم مرحباً: عقد بسيط\u003C\u002Fh2>\n\u003Cp>لنكتب عقداً يُرجع الكلمة 32 بايت \u003Ccode>0x01\u003C\u002Fcode> لأي استدعاء:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro MAIN() = takes(0) returns(0) {\n    0x01            \u002F\u002F [0x01]\n    0x00            \u002F\u002F [0x00, 0x01]\n    mstore          \u002F\u002F []          — memory[0x00..0x20] = 0x01\n    0x20            \u002F\u002F [0x20]\n    0x00            \u002F\u002F [0x00, 0x20]\n    return          \u002F\u002F توقف — إرجاع memory[0x00..0x20]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>ترجمة:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">huffc src\u002FHelloWorld.huff -r\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>العلم \u003Ccode>-r\u003C\u002Fcode> يُخرج بايتكود التشغيل. سترى شيئاً مثل \u003Ccode>600160005260206000f3\u003C\u002Fcode> — 10 بايت. عقد Solidity يُرجع \u003Ccode>1\u003C\u002Fcode> يترجم إلى 200+ بايت تقريباً لأن solc يُصدر مرسل دوال كامل وتجزئة البيانات الوصفية وإعداد مؤشر الذاكرة الحرة ومرمز ABI.\u003C\u002Fp>\n\u003Ch2 id=\"\">الماكرو مقابل الدوال\u003C\u002Fh2>\n\u003Cp>Huff لديها نوعان لإعادة استخدام الكود: \u003Cstrong>الماكرو\u003C\u002Fstrong> و\u003Cstrong>الدوال\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Ch3>الماكرو (\u003Ccode>#define macro\u003C\u002Fcode>)\u003C\u002Fh3>\n\u003Cp>يتم تضمين الماكرو في كل موقع استدعاء. لا حمل JUMP إضافي، لا غاز إضافي — المترجم ينسخ أكواد التشغيل حرفياً في المستدعي. هذا هو الخيار الافتراضي والمفضل للكود الحرج من حيث الغاز.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro REQUIRE_NOT_ZERO() = takes(1) returns(0) {\n    \u002F\u002F takes: [value]\n    continue        \u002F\u002F [continue_dest, value]\n    jumpi           \u002F\u002F []  — قفز إذا value != 0\n    0x00 0x00 revert\n    continue:\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>الدوال (\u003Ccode>#define fn\u003C\u002Fcode>)\u003C\u002Fh3>\n\u003Cp>الدوال تولد زوج JUMP\u002FJUMPDEST فعلي. توفر حجم البايتكود على حساب ~22 غاز إضافي لكل استدعاء. استخدمها فقط عندما يكون حجم البايتكود أهم من الغاز.\u003C\u002Fp>\n\u003Ch2 id=\"\">العلامات ووجهات القفز\u003C\u002Fh2>\n\u003Cp>العلامات في Huff هي مواقع JUMPDEST مسماة. يحلها المترجم إلى إزاحات بايتكود محددة في وقت الترجمة.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro LOOP_EXAMPLE() = takes(1) returns(1) {\n    \u002F\u002F takes: [n]\n    0x00                \u002F\u002F [acc, n]\n    loop:\n        dup2            \u002F\u002F [n, acc, n]\n        iszero          \u002F\u002F [n==0?, acc, n]\n        done jumpi      \u002F\u002F [acc, n]\n        swap1           \u002F\u002F [n, acc]\n        0x01 swap1 sub  \u002F\u002F [n-1, acc]\n        swap1           \u002F\u002F [acc, n-1]\n        0x01 add        \u002F\u002F [acc+1, n-1]\n        loop jump\n    done:\n        swap1 pop       \u002F\u002F [acc]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"takes-returns\">takes() وreturns()\u003C\u002Fh2>\n\u003Cp>توصيفات \u003Ccode>takes(n)\u003C\u002Fcode> و\u003Ccode>returns(m)\u003C\u002Fcode> على الماكرو والدوال هي توثيق وتلميحات للمترجم. تخبر القارئ — ومدقق المكدس في مترجم Huff — عن عدد عناصر المكدس التي يتوقع الكتلة استهلاكها وإنتاجها.\u003C\u002Fp>\n\u003Ch2 id=\"huff-solidity\">المقارنة: Huff مقابل بايتكود Solidity\u003C\u002Fh2>\n\u003Cp>لنأخذ دالة عرض بسيطة \u003Ccode>getValue()\u003C\u002Fcode> تُرجع فتحة تخزين:\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Solidity:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">function getValue() external view returns (uint256) {\n    return value;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>solc يولد ~40 بايت للمرسل + ترميز ABI.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>مكافئ Huff:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define function getValue() view returns (uint256)\n\n#define macro GET_VALUE() = takes(0) returns(0) {\n    [VALUE_SLOT]    \u002F\u002F [slot]\n    sload           \u002F\u002F [value]\n    0x00 mstore     \u002F\u002F []  — تخزين في الذاكرة\n    0x20 0x00 return\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>نسخة Huff هي 12 بايت من البايتكود للجسم. بدون حمل ترميز ABI أو مؤشر الذاكرة الحرة أو تجزئة البيانات الوصفية.\u003C\u002Fp>\n\u003Ch2 id=\"\">الثوابت وفتحات التخزين\u003C\u002Fh2>\n\u003Cp>ثوابت Huff هي قيم وقت الترجمة يتم تضمينها كتعليمات PUSH:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define constant VALUE_SLOT = 0x00\n#define constant OWNER_SLOT = 0x01\n#define constant MAX_UINT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>الاستخدام: \u003Ccode>[VALUE_SLOT]\u003C\u002Fcode> يدفع \u003Ccode>0x00\u003C\u002Fcode>. الثوابت تحسن القراءة بدون تكلفة غاز — هي بنيوية بحتة.\u003C\u002Fp>\n\u003Ch2 id=\"\">التضمينات وبنية المشروع\u003C\u002Fh2>\n\u003Cp>مشاريع Huff الحقيقية تقسم الكود عبر ملفات متعددة:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">\u002F\u002F src\u002FMain.huff\n#include \".\u002Futils\u002FSafeMath.huff\"\n#include \".\u002Finterfaces\u002FIERC20.huff\"\n#include \".\u002FDispatcher.huff\"\n\n#define macro MAIN() = takes(0) returns(0) {\n    DISPATCHER()\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"huff\">متى تستخدم Huff\u003C\u002Fh2>\n\u003Cp>Huff ليست لغة عامة الأغراض. استخدمها عندما:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>الغاز هو القيد الرئيسي\u003C\u002Fstrong> — عقود MEV حيث 100 غاز تحدد الربحية\u003C\u002Fli>\n\u003Cli>\u003Cstrong>حجم البايتكود مهم\u003C\u002Fstrong> — عقود مُنشأة بواسطة عقود أخرى (مصانع CREATE2)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>تحتاج إرسال مخصص\u003C\u002Fstrong> — جداول القفز، محددات محزومة بالبتات\u003C\u002Fli>\n\u003Cli>\u003Cstrong>تتعلم EVM\u003C\u002Fstrong> — لا شيء يعلم EVM أفضل من كتابة أكواد تشغيل خام\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">الملخص\u003C\u002Fh2>\n\u003Cp>Huff تمنحك خطاً مباشراً إلى بايتكود EVM مع تجريد كافٍ للبقاء عاقلاً. الماكرو تضمن الكود لإعادة استخدام بدون حمل. العلامات تتعامل مع حساب إزاحات القفز. توصيفات \u003Ccode>takes\u003C\u002Fcode>\u002F\u003Ccode>returns\u003C\u002Fcode> تكتشف أخطاء المكدس مبكراً.\u003C\u002Fp>\n","ar","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:32.444469Z","مقدمة في Huff لغة تجميع EVM منخفضة المستوى. تعلم الماكرو والعلامات وtakes\u002Freturns ومقارنة بايتكود Huff مع مخرجات Solidity.","لغة Huff 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-000000000017","Huff","huff","بلوكتشين",[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"]