توكن الغاز الخاص بـ DuskEVM الخاص بـ DUSK يحتوي على 18 رقمًا عشريًا، لا تستخدم عادةً 6 أرقام عشرية مثل USDC
yوم نشر العقد على testnet، كتبت وفقًا لعادة عضلاتي في DeFi وتمرير المعاملات: transfer(addr, 1000000) بهدف تحويل 1 DUSK. لكن العقد رجع خطأ: insufficient balance — مع أن محفظتي كانت تحتوي 15 DUSK للاختبار. من خلال Blockscout فهمت السبب: DUSK في الشبكة الرئيسية وداخل DuskEVM كلاهما 18 رقمًا عشريًا (مثل ETH)، وليس 6 مثل USDC، ولا 8 مثل بعض توكنات BEP-20. 1 DUSK = 1000000000000000000 وحدة حدّية (أصغر وحدة).
هذا الفخ سهل جدًا الوقوع فيه عند كتابة كود يعمل عبر بيئات مختلفة: في Solidity كتبت مثلًا uint amount = 1 * 10**18 وهو صحيح، لكن واجهة JS الأمامية نسخت ethers.parseUnits("1", 6) فكان خطأ؛ سكربت Node الذي يقرأ سعر DUSK من Binance REST (وحدة التسعير: 1 DUSK = x U) لا مشكلة فيه، لكن عند إنشاء معاملة DuskEVM إن استخدمت 1e6 على أنه 1 DUSK لحرق غاز، ستنتهي المعاملة إلى صفر وتدفع base fee بدون نتيجة.
والأكثر تعقيدًا أن تقدير رسوم DuskEVM ينقسم إلى جزأين: L2 exec fee يُحسب بعدد 18 رقمًا عشريًا من DUSK، وL1(DA) fee أيضًا يُدفع بـ DUSK 18 رقمًا ويذهب إلى مُنتِجي DuskDS. في Remix، عندما ملأت gas limit أول مرة، أدخلت قيمة في خانة value خطأ: 2000000 (كأنها 2 DUSK). في الحقيقة كانت 0.000002 DUSK، أي أقل من base fee فتم رفضها. بعد تعديلها إلى 2000000000000000000 (2e18) نجحت.
وبنفس المنطق المتغيرات السرية المعلّمة في Hedger: عند @hedged uint256 shares تمثل 1000 حصة سندات، يجب تخزين 1000 * 10**18. حتى قبل أن يُفكك view key سترى الواجهة 1000 بعد formatUnits(18)، ولا تظنه 0.001 لأنك استخدمت formatUnits(6).
أليس أول معاملة بعد التحويل من ERC-20 أيضًا عضّتك بسبب أماكن الكسور؟
@Dusk $DUSK #dusk
yوم نشر العقد على testnet، كتبت وفقًا لعادة عضلاتي في DeFi وتمرير المعاملات: transfer(addr, 1000000) بهدف تحويل 1 DUSK. لكن العقد رجع خطأ: insufficient balance — مع أن محفظتي كانت تحتوي 15 DUSK للاختبار. من خلال Blockscout فهمت السبب: DUSK في الشبكة الرئيسية وداخل DuskEVM كلاهما 18 رقمًا عشريًا (مثل ETH)، وليس 6 مثل USDC، ولا 8 مثل بعض توكنات BEP-20. 1 DUSK = 1000000000000000000 وحدة حدّية (أصغر وحدة).
هذا الفخ سهل جدًا الوقوع فيه عند كتابة كود يعمل عبر بيئات مختلفة: في Solidity كتبت مثلًا uint amount = 1 * 10**18 وهو صحيح، لكن واجهة JS الأمامية نسخت ethers.parseUnits("1", 6) فكان خطأ؛ سكربت Node الذي يقرأ سعر DUSK من Binance REST (وحدة التسعير: 1 DUSK = x U) لا مشكلة فيه، لكن عند إنشاء معاملة DuskEVM إن استخدمت 1e6 على أنه 1 DUSK لحرق غاز، ستنتهي المعاملة إلى صفر وتدفع base fee بدون نتيجة.
والأكثر تعقيدًا أن تقدير رسوم DuskEVM ينقسم إلى جزأين: L2 exec fee يُحسب بعدد 18 رقمًا عشريًا من DUSK، وL1(DA) fee أيضًا يُدفع بـ DUSK 18 رقمًا ويذهب إلى مُنتِجي DuskDS. في Remix، عندما ملأت gas limit أول مرة، أدخلت قيمة في خانة value خطأ: 2000000 (كأنها 2 DUSK). في الحقيقة كانت 0.000002 DUSK، أي أقل من base fee فتم رفضها. بعد تعديلها إلى 2000000000000000000 (2e18) نجحت.
وبنفس المنطق المتغيرات السرية المعلّمة في Hedger: عند @hedged uint256 shares تمثل 1000 حصة سندات، يجب تخزين 1000 * 10**18. حتى قبل أن يُفكك view key سترى الواجهة 1000 بعد formatUnits(18)، ولا تظنه 0.001 لأنك استخدمت formatUnits(6).
أليس أول معاملة بعد التحويل من ERC-20 أيضًا عضّتك بسبب أماكن الكسور؟
@Dusk $DUSK #dusk