مؤخراً أثناء كتابة دليل تطوير تبادل لامركزي، قمت بالرجوع إلى تنفيذ كود Uniswap V3، وتعلمت العديد من النقاط القيمة. كوني مطوراً يحاول لأول مرة تطوير عقود Defi، فإن هذه التقنيات ستكون مفيدة جداً للمبتدئين الذين يرغبون في تعلم تطوير العقود.
عنوان عقد النشر القابل للتنبؤ
عادةً ما يبدو أن العنوان الناتج عن نشر العقد عشوائي، لأنه يتعلق بـ nonce. ولكن في بعض الحالات، نحتاج إلى استنتاج عنوان العقد من خلال أزواج التداول والمعلومات ذات الصلة، مثل تحديد صلاحيات التداول أو الحصول على عنوان المسبح.
يستخدم Uniswap طريقة CREATE2 لإنشاء العقود، من خلال إضافة معلمة salt لجعل العنوان الناتج قابلاً للتنبؤ. منطق حساب العنوان الجديد هو: hash("0xFF"، عنوان المنشئ، salt، initcode).
الاستخدام الذكي لوظائف الاسترجاع
يمكن للعقود في Solidity استدعاء بعضها البعض. في بعض السيناريوهات، يعد استدعاء A لطريقة B، وعودة B إلى A في الطريقة المستدعاة أمرًا مفيدًا.
في Uniswap، عند استدعاء طريقة swap لعقد UniswapV3Pool للتداول، فإنه سيقوم باستدعاء swapCallback، وتمرير العملات الرمزية المطلوبة لهذه الصفقة. يجب على الطرف المستدعي في الاستدعاء أن يقوم بتحويل العملات الرمزية المطلوبة إلى UniswapV3Pool، بدلاً من تقسيم طريقة swap إلى جزئين. هذا يضمن أمان طريقة swap وتنفيذها الكامل، دون الحاجة إلى تسجيل المتغيرات بشكل معقد.
استخدام الاستثناءات لنقل المعلومات، واستخدام try catch لتنفيذ تقدير المعاملات
في عقد Quoter الخاص بـ Uniswap، يتم تنفيذ طريقة swap لـ UniswapV3Pool داخل try catch. وذلك لمحاكاة تقدير توكنات التداول المطلوبة لطريقة swap، ولكن أثناء التقدير لن يتم إجراء تبادل فعلي للتوكنات، لذا ستظهر رسالة خطأ.
تقوم Uniswap بإلقاء أخطاء خاصة في دالة رد الاتصال الخاصة بالتجارة، ثم تلتقط هذا الخطأ وتستخلص المعلومات المطلوبة من رسالة الخطأ. تبدو هذه الطريقة وكأنها حيلة، لكنها عملية للغاية، حيث لا حاجة لتعديل طريقة التبديل لتقدير احتياجات التجارة، كما أن المنطق أبسط.
استخدام الأعداد الكبيرة لحل مشكلة الدقة
هناك الكثير من المنطق الحسابي في كود Uniswap، مثل حساب الرموز المتبادلة بناءً على السعر الحالي والسيولة. لتجنب فقدان الدقة في عمليات القسمة، غالبًا ما تستخدم عملية "<< FixedPoint96.RESOLUTION"، أي الإزاحة لليسار بمقدار 96 بت، مما يعادل الضرب في 2^96.
يمكن ضمان الدقة أثناء إجراء عمليات القسمة بعد التحريك لليسار، دون تجاوز الحدود في المعاملات العادية. على الرغم من أنه لا يزال سيكون هناك فقدان في دقة الوحدة الدنيا من الناحية النظرية، إلا أن هذا مقبول.
حساب الأرباح بطريقة المشاركة
يحتاج Uniswap إلى تسجيل عائدات رسوم المعاملات لمقدمي السيولة LP(. لتجنب استهلاك كمية كبيرة من الغاز من خلال تسجيل الرسوم لكل LP في كل صفقة، اعتمد Uniswap طريقة ذكية.
تتضمن بنية Position feeGrowthInside0LastX128 و feeGrowthInside1LastX128، والتي تسجل الرسوم التي ينبغي أن يحصل عليها كل سيولة عند آخر سحب للرسوم من كل مركز. يكفي تسجيل إجمالي الرسوم والرسوم المخصصة لكل سيولة، وعند سحب LP، يتم حساب الرسوم القابلة للسحب بناءً على السيولة المحتفظ بها.
![Web3 سلسلة المبتدئين: النصائح الصغيرة في تطوير العقود التي تعلمتها من كود Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
استراتيجيات الحصول على المعلومات على السلسلة
ليس من الضروري الحصول على جميع المعلومات من السلسلة. إن التخزين على السلسلة مكلف نسبيًا، ويمكن تخزين العديد من المعلومات في قواعد بيانات عادية، ومزامنتها بانتظام من السلسلة.
يمكن تخزين قوائم أحواض التداول ومعلومات أحواض التداول وما إلى ذلك في قاعدة بيانات عادية، دون الحاجة إلى استدعاء واجهة RPC لخدمات السلسلة أو العقدة في الوقت الفعلي. بالطبع، تظل المعاملات الرئيسية على السلسلة.
تقسيم العقود واستخدام العقود القياسية
يمكن أن يحتوي المشروع على عدة عقود تم نشرها فعليًا. حتى إذا كان هناك عقد واحد فقط تم نشره فعليًا، يمكن تقسيم الكود إلى عدة عقود للصيانة من خلال الوراثة.
على سبيل المثال، يرث عقد NonfungiblePositionManager الخاص بـ Uniswap العديد من العقود. باستخدام عقد ERC721 من OpenZeppelin، يصبح من السهل إدارة المراكز من خلال NFTs، كما يعزز كفاءة التطوير.
خاتمة
الممارسة هي أفضل طريقة للتعلم. حاول تنفيذ نسخة بسيطة من بورصة لامركزية، يمكنك من خلالها فهم كود Uniswap بشكل أعمق، وتعلم المزيد من النقاط المعرفية في المشاريع الحقيقية. إذا كنت مهتمًا بتطوير مشاريع Web3 وDefi، يمكنك الرجوع إلى الدورات العملية ذات الصلة، وإكمال نسخة بسيطة من البورصة تدريجياً.
![Web3 سلسلة المبتدئين: النصائح الصغيرة لتطوير العقود التي تعلمتها من كود Uniswap])https://img-cdn.gateio.im/webp-social/moments-f95ddc9d89809cf11dbe65b9bafda157.webp(
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
كشف شفرة Uniswap: 7 نصائح لتطوير العقود تساعد مبتدئي Defi
نصائح تطوير العقود التي تعلمتها من كود Uniswap
مؤخراً أثناء كتابة دليل تطوير تبادل لامركزي، قمت بالرجوع إلى تنفيذ كود Uniswap V3، وتعلمت العديد من النقاط القيمة. كوني مطوراً يحاول لأول مرة تطوير عقود Defi، فإن هذه التقنيات ستكون مفيدة جداً للمبتدئين الذين يرغبون في تعلم تطوير العقود.
عنوان عقد النشر القابل للتنبؤ
عادةً ما يبدو أن العنوان الناتج عن نشر العقد عشوائي، لأنه يتعلق بـ nonce. ولكن في بعض الحالات، نحتاج إلى استنتاج عنوان العقد من خلال أزواج التداول والمعلومات ذات الصلة، مثل تحديد صلاحيات التداول أو الحصول على عنوان المسبح.
يستخدم Uniswap طريقة CREATE2 لإنشاء العقود، من خلال إضافة معلمة salt لجعل العنوان الناتج قابلاً للتنبؤ. منطق حساب العنوان الجديد هو: hash("0xFF"، عنوان المنشئ، salt، initcode).
الاستخدام الذكي لوظائف الاسترجاع
يمكن للعقود في Solidity استدعاء بعضها البعض. في بعض السيناريوهات، يعد استدعاء A لطريقة B، وعودة B إلى A في الطريقة المستدعاة أمرًا مفيدًا.
في Uniswap، عند استدعاء طريقة swap لعقد UniswapV3Pool للتداول، فإنه سيقوم باستدعاء swapCallback، وتمرير العملات الرمزية المطلوبة لهذه الصفقة. يجب على الطرف المستدعي في الاستدعاء أن يقوم بتحويل العملات الرمزية المطلوبة إلى UniswapV3Pool، بدلاً من تقسيم طريقة swap إلى جزئين. هذا يضمن أمان طريقة swap وتنفيذها الكامل، دون الحاجة إلى تسجيل المتغيرات بشكل معقد.
استخدام الاستثناءات لنقل المعلومات، واستخدام try catch لتنفيذ تقدير المعاملات
في عقد Quoter الخاص بـ Uniswap، يتم تنفيذ طريقة swap لـ UniswapV3Pool داخل try catch. وذلك لمحاكاة تقدير توكنات التداول المطلوبة لطريقة swap، ولكن أثناء التقدير لن يتم إجراء تبادل فعلي للتوكنات، لذا ستظهر رسالة خطأ.
تقوم Uniswap بإلقاء أخطاء خاصة في دالة رد الاتصال الخاصة بالتجارة، ثم تلتقط هذا الخطأ وتستخلص المعلومات المطلوبة من رسالة الخطأ. تبدو هذه الطريقة وكأنها حيلة، لكنها عملية للغاية، حيث لا حاجة لتعديل طريقة التبديل لتقدير احتياجات التجارة، كما أن المنطق أبسط.
استخدام الأعداد الكبيرة لحل مشكلة الدقة
هناك الكثير من المنطق الحسابي في كود Uniswap، مثل حساب الرموز المتبادلة بناءً على السعر الحالي والسيولة. لتجنب فقدان الدقة في عمليات القسمة، غالبًا ما تستخدم عملية "<< FixedPoint96.RESOLUTION"، أي الإزاحة لليسار بمقدار 96 بت، مما يعادل الضرب في 2^96.
يمكن ضمان الدقة أثناء إجراء عمليات القسمة بعد التحريك لليسار، دون تجاوز الحدود في المعاملات العادية. على الرغم من أنه لا يزال سيكون هناك فقدان في دقة الوحدة الدنيا من الناحية النظرية، إلا أن هذا مقبول.
حساب الأرباح بطريقة المشاركة
يحتاج Uniswap إلى تسجيل عائدات رسوم المعاملات لمقدمي السيولة LP(. لتجنب استهلاك كمية كبيرة من الغاز من خلال تسجيل الرسوم لكل LP في كل صفقة، اعتمد Uniswap طريقة ذكية.
تتضمن بنية Position feeGrowthInside0LastX128 و feeGrowthInside1LastX128، والتي تسجل الرسوم التي ينبغي أن يحصل عليها كل سيولة عند آخر سحب للرسوم من كل مركز. يكفي تسجيل إجمالي الرسوم والرسوم المخصصة لكل سيولة، وعند سحب LP، يتم حساب الرسوم القابلة للسحب بناءً على السيولة المحتفظ بها.
![Web3 سلسلة المبتدئين: النصائح الصغيرة في تطوير العقود التي تعلمتها من كود Uniswap])https://img-cdn.gateio.im/webp-social/moments-45e66af69435e6d4412ae506e77ab893.webp(
استراتيجيات الحصول على المعلومات على السلسلة
ليس من الضروري الحصول على جميع المعلومات من السلسلة. إن التخزين على السلسلة مكلف نسبيًا، ويمكن تخزين العديد من المعلومات في قواعد بيانات عادية، ومزامنتها بانتظام من السلسلة.
يمكن تخزين قوائم أحواض التداول ومعلومات أحواض التداول وما إلى ذلك في قاعدة بيانات عادية، دون الحاجة إلى استدعاء واجهة RPC لخدمات السلسلة أو العقدة في الوقت الفعلي. بالطبع، تظل المعاملات الرئيسية على السلسلة.
تقسيم العقود واستخدام العقود القياسية
يمكن أن يحتوي المشروع على عدة عقود تم نشرها فعليًا. حتى إذا كان هناك عقد واحد فقط تم نشره فعليًا، يمكن تقسيم الكود إلى عدة عقود للصيانة من خلال الوراثة.
على سبيل المثال، يرث عقد NonfungiblePositionManager الخاص بـ Uniswap العديد من العقود. باستخدام عقد ERC721 من OpenZeppelin، يصبح من السهل إدارة المراكز من خلال NFTs، كما يعزز كفاءة التطوير.
خاتمة
الممارسة هي أفضل طريقة للتعلم. حاول تنفيذ نسخة بسيطة من بورصة لامركزية، يمكنك من خلالها فهم كود Uniswap بشكل أعمق، وتعلم المزيد من النقاط المعرفية في المشاريع الحقيقية. إذا كنت مهتمًا بتطوير مشاريع Web3 وDefi، يمكنك الرجوع إلى الدورات العملية ذات الصلة، وإكمال نسخة بسيطة من البورصة تدريجياً.
![Web3 سلسلة المبتدئين: النصائح الصغيرة لتطوير العقود التي تعلمتها من كود Uniswap])https://img-cdn.gateio.im/webp-social/moments-f95ddc9d89809cf11dbe65b9bafda157.webp(