[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-17-ikhtibar-uqud-huff-foundry-fork-ghaz":3},{"article":4,"author":59},{"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":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":39,"related_articles":40},"d9000000-0000-0000-0000-000000000117","a0000000-0000-0000-0000-000000000092","Deep EVM #17: اختبار عقود Huff — اختبارات Fork في Foundry وتأكيدات الغاز","deep-evm-17-ikhtibar-uqud-huff-foundry-fork-ghaz","اختبار عقود Huff منخفضة المستوى باستخدام Foundry: إعداد اختبارات fork، تأكيدات الغاز، واستراتيجيات التغطية للعقود بدون ABI قياسي.","## تحدي اختبار Huff\n\nعقود Huff ليس لها ABI قياسي ولا أنواع Solidity — إنها مجرد بايتكود. كيف تكتب اختبارات لها؟ الإجابة: Foundry مع foundry-huff.\n\n## إعداد بيئة الاختبار\n\n```bash\nforge init huff-project\nforge install huff-language\u002Ffoundry-huff\n```\n\nفي `foundry.toml`:\n```toml\n[profile.default]\nsrc = \"src\"\ntest = \"test\"\nlibs = [\"lib\"]\nffi = true  # مطلوب لـ foundry-huff\n```\n\n## نشر عقد Huff في الاختبار\n\n```solidity\n\u002F\u002F test\u002FTokenSwap.t.sol\nimport {Test} from \"forge-std\u002FTest.sol\";\nimport {HuffDeployer} from \"foundry-huff\u002FHuffDeployer.sol\";\n\ncontract TokenSwapTest is Test {\n    address public swapContract;\n    \n    function setUp() public {\n        swapContract = HuffDeployer.deploy(\"TokenSwap\");\n    }\n    \n    function testOwner() public {\n        (bool success, bytes memory data) = swapContract.staticcall(\n            abi.encodeWithSignature(\"owner()\")\n        );\n        assertTrue(success);\n        address owner = abi.decode(data, (address));\n        assertEq(owner, address(this));\n    }\n}\n```\n\n## اختبارات Fork\n\nاختبارات Fork تنفذ ضد حالة شبكة رئيسية حقيقية:\n\n```solidity\nfunction testSwapOnMainnetFork() public {\n    vm.createSelectFork(\"mainnet\", 18_000_000);\n    \n    address weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n    address usdc = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;\n    \n    \u002F\u002F إعداد الرصيد\n    deal(weth, address(this), 10 ether);\n    IERC20(weth).approve(swapContract, type(uint256).max);\n    \n    \u002F\u002F تنفيذ المبادلة\n    (bool success,) = swapContract.call(\n        abi.encodeWithSignature(\n            \"swap(address,address,uint256)\",\n            weth, usdc, 1 ether\n        )\n    );\n    assertTrue(success);\n    \n    \u002F\u002F تحقق من النتيجة\n    uint256 usdcBalance = IERC20(usdc).balanceOf(address(this));\n    assertGt(usdcBalance, 0);\n}\n```\n\n## تأكيدات الغاز\n\nتتبع استهلاك الغاز ومنع التراجع:\n\n```solidity\nfunction testGasConsumption() public {\n    uint256 gasBefore = gasleft();\n    \n    (bool success,) = swapContract.call(\n        abi.encodeWithSignature(\"owner()\")\n    );\n    assertTrue(success);\n    \n    uint256 gasUsed = gasBefore - gasleft();\n    \n    \u002F\u002F تأكد أن الغاز لا يتجاوز الحد\n    assertLt(gasUsed, 5000, \"owner() يستهلك غاز أكثر من المتوقع\");\n}\n```\n\nمع `--gas-report`:\n```bash\nforge test --gas-report\n```\n\n## اختبار التراجعات\n\n```solidity\nfunction testRevertOnZeroAmount() public {\n    (bool success,) = swapContract.call(\n        abi.encodeWithSignature(\n            \"swap(address,address,uint256)\",\n            address(0x1), address(0x2), 0\n        )\n    );\n    assertFalse(success, \"يجب أن يتراجع عند المبلغ صفر\");\n}\n\nfunction testRevertOnUnknownSelector() public {\n    (bool success,) = swapContract.call(\n        abi.encodeWithSelector(bytes4(0xdeadbeef))\n    );\n    assertFalse(success, \"يجب أن يتراجع عند محدد غير معروف\");\n}\n```\n\n## اختبارات الطفرات (Mutation Testing)\n\nتأكد من أن اختباراتك تكتشف الأخطاء فعلاً عن طريق إدخال طفرات مقصودة في البايتكود وتحقق من فشل الاختبارات.\n\n## استراتيجيات التغطية\n\nبما أن Huff ليس لها أداة تغطية مدمجة:\n\n1. **اختبر كل محدد** — تأكد من وجود اختبار لكل دالة\n2. **اختبر الحالات الحدية** — أصفار، قيم قصوى، عناوين صفرية\n3. **اختبر التراجعات** — كل مسار revert يجب أن يُختبر\n4. **اختبر التفاعلات** — استدعاءات متتالية، حالات مختلفة\n\n## الخلاصة\n\nFoundry يوفر بيئة اختبار ممتازة لعقود Huff عبر foundry-huff. اختبارات Fork تضمن التوافق مع الشبكة الرئيسية، وتأكيدات الغاز تمنع التراجع في الأداء. القاعدة: إذا لم تستطع اختباره، لا تنشره.","\u003Ch2 id=\"huff\">تحدي اختبار Huff\u003C\u002Fh2>\n\u003Cp>عقود Huff ليس لها ABI قياسي ولا أنواع Solidity — إنها مجرد بايتكود. كيف تكتب اختبارات لها؟ الإجابة: Foundry مع foundry-huff.\u003C\u002Fp>\n\u003Ch2 id=\"\">إعداد بيئة الاختبار\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-bash\">forge init huff-project\nforge install huff-language\u002Ffoundry-huff\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>في \u003Ccode>foundry.toml\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-toml\">[profile.default]\nsrc = \"src\"\ntest = \"test\"\nlibs = [\"lib\"]\nffi = true  # مطلوب لـ foundry-huff\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"huff\">نشر عقد Huff في الاختبار\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F test\u002FTokenSwap.t.sol\nimport {Test} from \"forge-std\u002FTest.sol\";\nimport {HuffDeployer} from \"foundry-huff\u002FHuffDeployer.sol\";\n\ncontract TokenSwapTest is Test {\n    address public swapContract;\n    \n    function setUp() public {\n        swapContract = HuffDeployer.deploy(\"TokenSwap\");\n    }\n    \n    function testOwner() public {\n        (bool success, bytes memory data) = swapContract.staticcall(\n            abi.encodeWithSignature(\"owner()\")\n        );\n        assertTrue(success);\n        address owner = abi.decode(data, (address));\n        assertEq(owner, address(this));\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"fork\">اختبارات Fork\u003C\u002Fh2>\n\u003Cp>اختبارات Fork تنفذ ضد حالة شبكة رئيسية حقيقية:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">function testSwapOnMainnetFork() public {\n    vm.createSelectFork(\"mainnet\", 18_000_000);\n    \n    address weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n    address usdc = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;\n    \n    \u002F\u002F إعداد الرصيد\n    deal(weth, address(this), 10 ether);\n    IERC20(weth).approve(swapContract, type(uint256).max);\n    \n    \u002F\u002F تنفيذ المبادلة\n    (bool success,) = swapContract.call(\n        abi.encodeWithSignature(\n            \"swap(address,address,uint256)\",\n            weth, usdc, 1 ether\n        )\n    );\n    assertTrue(success);\n    \n    \u002F\u002F تحقق من النتيجة\n    uint256 usdcBalance = IERC20(usdc).balanceOf(address(this));\n    assertGt(usdcBalance, 0);\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">تأكيدات الغاز\u003C\u002Fh2>\n\u003Cp>تتبع استهلاك الغاز ومنع التراجع:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">function testGasConsumption() public {\n    uint256 gasBefore = gasleft();\n    \n    (bool success,) = swapContract.call(\n        abi.encodeWithSignature(\"owner()\")\n    );\n    assertTrue(success);\n    \n    uint256 gasUsed = gasBefore - gasleft();\n    \n    \u002F\u002F تأكد أن الغاز لا يتجاوز الحد\n    assertLt(gasUsed, 5000, \"owner() يستهلك غاز أكثر من المتوقع\");\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>مع \u003Ccode>--gas-report\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">forge test --gas-report\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">اختبار التراجعات\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-solidity\">function testRevertOnZeroAmount() public {\n    (bool success,) = swapContract.call(\n        abi.encodeWithSignature(\n            \"swap(address,address,uint256)\",\n            address(0x1), address(0x2), 0\n        )\n    );\n    assertFalse(success, \"يجب أن يتراجع عند المبلغ صفر\");\n}\n\nfunction testRevertOnUnknownSelector() public {\n    (bool success,) = swapContract.call(\n        abi.encodeWithSelector(bytes4(0xdeadbeef))\n    );\n    assertFalse(success, \"يجب أن يتراجع عند محدد غير معروف\");\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"mutation-testing\">اختبارات الطفرات (Mutation Testing)\u003C\u002Fh2>\n\u003Cp>تأكد من أن اختباراتك تكتشف الأخطاء فعلاً عن طريق إدخال طفرات مقصودة في البايتكود وتحقق من فشل الاختبارات.\u003C\u002Fp>\n\u003Ch2 id=\"\">استراتيجيات التغطية\u003C\u002Fh2>\n\u003Cp>بما أن Huff ليس لها أداة تغطية مدمجة:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>اختبر كل محدد\u003C\u002Fstrong> — تأكد من وجود اختبار لكل دالة\u003C\u002Fli>\n\u003Cli>\u003Cstrong>اختبر الحالات الحدية\u003C\u002Fstrong> — أصفار، قيم قصوى، عناوين صفرية\u003C\u002Fli>\n\u003Cli>\u003Cstrong>اختبر التراجعات\u003C\u002Fstrong> — كل مسار revert يجب أن يُختبر\u003C\u002Fli>\n\u003Cli>\u003Cstrong>اختبر التفاعلات\u003C\u002Fstrong> — استدعاءات متتالية، حالات مختلفة\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">الخلاصة\u003C\u002Fh2>\n\u003Cp>Foundry يوفر بيئة اختبار ممتازة لعقود Huff عبر foundry-huff. اختبارات Fork تضمن التوافق مع الشبكة الرئيسية، وتأكيدات الغاز تمنع التراجع في الأداء. القاعدة: إذا لم تستطع اختباره، لا تنشره.\u003C\u002Fp>\n","ar","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:32.755497Z","اختبار عقود Huff مع Foundry — اختبارات Fork وتأكيدات الغاز","اختبار عقود Huff مع Foundry: اختبارات fork، تأكيدات الغاز، اختبارات التراجع، واستراتيجيات التغطية.","اختبار Huff Foundry",null,"index, follow",[22,27,31,35],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000021","Foundry","foundry",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":36,"name":37,"slug":38,"created_at":26},"c0000000-0000-0000-0000-000000000017","Huff","huff","بلوكتشين",[41,47,53],{"id":42,"title":43,"slug":44,"excerpt":45,"locale":12,"category_name":39,"published_at":46},"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":48,"title":49,"slug":50,"excerpt":51,"locale":12,"category_name":39,"published_at":52},"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":54,"title":55,"slug":56,"excerpt":57,"locale":12,"category_name":39,"published_at":58},"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":60,"slug":61,"bio":62,"photo_url":19,"linkedin":19,"role":63,"created_at":64,"updated_at":64},"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"]