نصائح صغيرة لتطوير العقود: الدروس المستفادة من شفرة Uniswap
مؤخراً، أثناء كتابة دليل تطوير بورصة لامركزية، كنت أستند إلى تنفيذ Uniswap V3 وتعلمت العديد من النقاط المثيرة للاهتمام. كوني مبتدئاً في محاولة تطوير عقود Defi، يجب أن تكون هذه التقنيات مفيدة جداً للمبتدئين الآخرين الذين يرغبون في تعلم تطوير العقود.
عنوان نشر العقد القابل للتنبؤ
عادةً ما تبدو العناوين الناتجة عن نشر العقود عشوائية، ويصعب التنبؤ بها. لكن في بعض الحالات، نحتاج إلى استنتاج عنوان العقد من خلال معلومات المعاملات المتقابلة، مثل تحديد صلاحيات المعاملات أو الحصول على عنوان التجمع.
تستخدم Uniswap طريقة CREATE2 لإنشاء العقد، مع إضافة معلمة salt لجعل العنوان قابلًا للتنبؤ. منطق إنشاء العنوان الجديد هو: hash("0xFF"، عنوان المنشئ، salt، initcode). هذه الطريقة تجعل عنوان العقد قابلًا للتنبؤ، مما يجعله مفيدًا للغاية.
الاستخدام الذكي لدوال الاستدعاء
يمكن للعقود في Solidity أن تستدعي بعضها البعض. في بعض السيناريوهات، يستدعي A طريقة B، ثم يقوم B باستدعاء A في الطريقة المستدعاة، وهذه الحالة مفيدة جداً.
تستخدم معاملات swap في Uniswap آلية الاسترجاع. طريقة swap في UniswapV3Pool ستستدعي swapCallback، مع تمرير الكمية الفعلية المطلوبة من الرموز. يجب على الجهة المستدعية نقل الرموز في الاسترجاع، مما يضمن التنفيذ الكامل والطبيعي لطريقة swap، دون الحاجة إلى تسجيل متغيرات معقدة.
استخدام الاستثناءات لنقل المعلومات، تنفيذ تقدير المعاملات باستخدام try catch
في عقد Quoter الخاص بـ Uniswap، يتم تنفيذ طريقة swap الخاصة بـ UniswapV3Pool داخل try catch. هذا لمحاكاة swap لتقدير الرموز المطلوبة للتداول، ولكن أثناء التقدير لن يتم تبادل الرموز فعليًا لذا ستظهر رسالة خطأ.
تقوم Uniswap بإلقاء أخطاء خاصة في دالة الاستدعاء ثم التقاط هذه الأخطاء واستخراج المعلومات المطلوبة منها. تبدو هذه الطريقة وكأنها حيلة، لكنها عملية جداً، حيث لا حاجة لتعديل طريقة التبديل لتقدير الطلب، مما يجعل المنطق أكثر بساطة.
استخدام الأعداد الكبيرة لحل مشاكل الدقة
يتضمن كود Uniswap الكثير من الحسابات، مثل حساب عدد الرموز التي يتم تبادلها بناءً على السعر الحالي والسيولة. لتجنب فقدان الدقة أثناء عمليات القسمة، غالبًا ما تستخدم عملية "<< FixedPoint96.RESOLUTION" في عملية الحساب، أي التحويل لليسار بمقدار 96 بت، مما يعادل الضرب في 2^96.
بعد التحريك لليسار ثم إجراء القسمة، يمكن ضمان الدقة في حالة عدم تجاوز المعاملات العادية. على الرغم من أنه لا يزال سيكون هناك خسارة دقيقة في الدقة من الناحية النظرية، إلا أنها مقبولة.
حساب الأرباح بطريقة Share
يجب على Uniswap تسجيل إيرادات رسوم المعاملات لمزودي السيولة LP( و). من الواضح أنه لا يمكن تسجيل رسوم المعاملات لكل LP في كل مرة يتم فيها إجراء معاملة، حيث سيؤدي ذلك إلى استهلاك كبير للغاز.
الحل هو تسجيل feeGrowthInside0LastX128 و feeGrowthInside1LastX128 في هيكل Position، مما يدل على رسوم المعاملات المستحقة لكل وحدة من السيولة عند سحب الرسوم في آخر مرة.
ما عليك سوى تسجيل إجمالي الرسوم و الرسوم المخصصة لكل وحدة من السيولة، وعند سحب LP يمكنك حساب الرسوم القابلة للسحب بناءً على السيولة التي تحتفظ بها. يشبه ذلك امتلاك الأسهم، فعند سحب الأرباح تحتاج فقط إلى معرفة الأرباح التاريخية لكل سهم والأرباح في آخر سحب.
ليس من الضروري الحصول على جميع المعلومات من السلسلة
تخزين البيانات على السلسلة مكلف نسبيًا، وليس من الضروري أن تكون جميع المعلومات على السلسلة أو يتم الحصول عليها منها. على سبيل المثال، العديد من الواجهات التي تستدعيها واجهة المستخدم الأمامية لـ Uniswap هي واجهات تقليدية من Web2.
يمكن تخزين قائمة أحواض التداول والمعلومات وما إلى ذلك في قاعدة بيانات عادية، وبعضها يحتاج إلى المزامنة من السلسلة بشكل دوري، لكن لا حاجة لاستدعاء واجهة RPC السلسلة أو العقد للحصول على البيانات في الوقت الحقيقي.
تقدم العديد من مزودي خدمات RPC في بلوكتشين واجهات متقدمة، مما يتيح الحصول على بيانات معينة بشكل أسرع وأرخص. غالبًا ما تستخدم هذه الواجهات التخزين المؤقت لتحسين الأداء والكفاءة.
بالطبع، لا تزال المعاملات الرئيسية تتم على السلسلة.
تعلم كيفية تقسيم العقود واستخدام العقود القياسية الموجودة
قد يحتوي المشروع على عدة عقود تم نشرها بالفعل. حتى إذا تم نشر عقد واحد فقط، يمكن تقسيم الكود إلى عدة عقود من خلال الوراثة للحفاظ عليه.
مثل عقد NonfungiblePositionManager الخاص بـ Uniswap الذي يرث من عدة عقود. حيث يستخدم عقد ERC721Permit مباشرةً تنفيذ ERC721 الخاص بـ OpenZeppelin، مما يسهل إدارة المراكز باستخدام NFT، ويزيد من كفاءة التطوير.
ملخص
قم بتطوير نسخة مبسطة من بورصة لامركزية بيديك، مما سيمكنك من فهم أعمق لتنفيذ Uniswap، واكتساب المزيد من النقاط المعرفية من المشاريع العملية. من المؤكد أن التعلم النظري مهم، ولكن الخبرة العملية أكثر قيمة. آمل أن تساعدك هذه النصائح الصغيرة في رحلتك لتطوير العقود.
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
تسجيلات الإعجاب 19
أعجبني
19
7
مشاركة
تعليق
0/400
GasWaster
· 07-16 11:49
يجب على كل من يتعلم العقود أن ينظر
شاهد النسخة الأصليةرد0
MissedAirdropAgain
· 07-16 07:39
لا يوجد وقت كافٍ لتعلم العقود...
شاهد النسخة الأصليةرد0
YieldWhisperer
· 07-14 20:20
رأيت هذا النمط بالضبط في dyydx في عام 2020... لا شيء جديد بصراحة
تحليل كود Uniswap: 7 نصائح لتطوير العقود الذكية
نصائح صغيرة لتطوير العقود: الدروس المستفادة من شفرة Uniswap
مؤخراً، أثناء كتابة دليل تطوير بورصة لامركزية، كنت أستند إلى تنفيذ Uniswap V3 وتعلمت العديد من النقاط المثيرة للاهتمام. كوني مبتدئاً في محاولة تطوير عقود Defi، يجب أن تكون هذه التقنيات مفيدة جداً للمبتدئين الآخرين الذين يرغبون في تعلم تطوير العقود.
عنوان نشر العقد القابل للتنبؤ
عادةً ما تبدو العناوين الناتجة عن نشر العقود عشوائية، ويصعب التنبؤ بها. لكن في بعض الحالات، نحتاج إلى استنتاج عنوان العقد من خلال معلومات المعاملات المتقابلة، مثل تحديد صلاحيات المعاملات أو الحصول على عنوان التجمع.
تستخدم Uniswap طريقة CREATE2 لإنشاء العقد، مع إضافة معلمة salt لجعل العنوان قابلًا للتنبؤ. منطق إنشاء العنوان الجديد هو: hash("0xFF"، عنوان المنشئ، salt، initcode). هذه الطريقة تجعل عنوان العقد قابلًا للتنبؤ، مما يجعله مفيدًا للغاية.
الاستخدام الذكي لدوال الاستدعاء
يمكن للعقود في Solidity أن تستدعي بعضها البعض. في بعض السيناريوهات، يستدعي A طريقة B، ثم يقوم B باستدعاء A في الطريقة المستدعاة، وهذه الحالة مفيدة جداً.
تستخدم معاملات swap في Uniswap آلية الاسترجاع. طريقة swap في UniswapV3Pool ستستدعي swapCallback، مع تمرير الكمية الفعلية المطلوبة من الرموز. يجب على الجهة المستدعية نقل الرموز في الاسترجاع، مما يضمن التنفيذ الكامل والطبيعي لطريقة swap، دون الحاجة إلى تسجيل متغيرات معقدة.
استخدام الاستثناءات لنقل المعلومات، تنفيذ تقدير المعاملات باستخدام try catch
في عقد Quoter الخاص بـ Uniswap، يتم تنفيذ طريقة swap الخاصة بـ UniswapV3Pool داخل try catch. هذا لمحاكاة swap لتقدير الرموز المطلوبة للتداول، ولكن أثناء التقدير لن يتم تبادل الرموز فعليًا لذا ستظهر رسالة خطأ.
تقوم Uniswap بإلقاء أخطاء خاصة في دالة الاستدعاء ثم التقاط هذه الأخطاء واستخراج المعلومات المطلوبة منها. تبدو هذه الطريقة وكأنها حيلة، لكنها عملية جداً، حيث لا حاجة لتعديل طريقة التبديل لتقدير الطلب، مما يجعل المنطق أكثر بساطة.
استخدام الأعداد الكبيرة لحل مشاكل الدقة
يتضمن كود Uniswap الكثير من الحسابات، مثل حساب عدد الرموز التي يتم تبادلها بناءً على السعر الحالي والسيولة. لتجنب فقدان الدقة أثناء عمليات القسمة، غالبًا ما تستخدم عملية "<< FixedPoint96.RESOLUTION" في عملية الحساب، أي التحويل لليسار بمقدار 96 بت، مما يعادل الضرب في 2^96.
بعد التحريك لليسار ثم إجراء القسمة، يمكن ضمان الدقة في حالة عدم تجاوز المعاملات العادية. على الرغم من أنه لا يزال سيكون هناك خسارة دقيقة في الدقة من الناحية النظرية، إلا أنها مقبولة.
حساب الأرباح بطريقة Share
يجب على Uniswap تسجيل إيرادات رسوم المعاملات لمزودي السيولة LP( و). من الواضح أنه لا يمكن تسجيل رسوم المعاملات لكل LP في كل مرة يتم فيها إجراء معاملة، حيث سيؤدي ذلك إلى استهلاك كبير للغاز.
الحل هو تسجيل feeGrowthInside0LastX128 و feeGrowthInside1LastX128 في هيكل Position، مما يدل على رسوم المعاملات المستحقة لكل وحدة من السيولة عند سحب الرسوم في آخر مرة.
ما عليك سوى تسجيل إجمالي الرسوم و الرسوم المخصصة لكل وحدة من السيولة، وعند سحب LP يمكنك حساب الرسوم القابلة للسحب بناءً على السيولة التي تحتفظ بها. يشبه ذلك امتلاك الأسهم، فعند سحب الأرباح تحتاج فقط إلى معرفة الأرباح التاريخية لكل سهم والأرباح في آخر سحب.
ليس من الضروري الحصول على جميع المعلومات من السلسلة
تخزين البيانات على السلسلة مكلف نسبيًا، وليس من الضروري أن تكون جميع المعلومات على السلسلة أو يتم الحصول عليها منها. على سبيل المثال، العديد من الواجهات التي تستدعيها واجهة المستخدم الأمامية لـ Uniswap هي واجهات تقليدية من Web2.
يمكن تخزين قائمة أحواض التداول والمعلومات وما إلى ذلك في قاعدة بيانات عادية، وبعضها يحتاج إلى المزامنة من السلسلة بشكل دوري، لكن لا حاجة لاستدعاء واجهة RPC السلسلة أو العقد للحصول على البيانات في الوقت الحقيقي.
تقدم العديد من مزودي خدمات RPC في بلوكتشين واجهات متقدمة، مما يتيح الحصول على بيانات معينة بشكل أسرع وأرخص. غالبًا ما تستخدم هذه الواجهات التخزين المؤقت لتحسين الأداء والكفاءة.
بالطبع، لا تزال المعاملات الرئيسية تتم على السلسلة.
تعلم كيفية تقسيم العقود واستخدام العقود القياسية الموجودة
قد يحتوي المشروع على عدة عقود تم نشرها بالفعل. حتى إذا تم نشر عقد واحد فقط، يمكن تقسيم الكود إلى عدة عقود من خلال الوراثة للحفاظ عليه.
مثل عقد NonfungiblePositionManager الخاص بـ Uniswap الذي يرث من عدة عقود. حيث يستخدم عقد ERC721Permit مباشرةً تنفيذ ERC721 الخاص بـ OpenZeppelin، مما يسهل إدارة المراكز باستخدام NFT، ويزيد من كفاءة التطوير.
ملخص
قم بتطوير نسخة مبسطة من بورصة لامركزية بيديك، مما سيمكنك من فهم أعمق لتنفيذ Uniswap، واكتساب المزيد من النقاط المعرفية من المشاريع العملية. من المؤكد أن التعلم النظري مهم، ولكن الخبرة العملية أكثر قيمة. آمل أن تساعدك هذه النصائح الصغيرة في رحلتك لتطوير العقود.