على عكس لغات البرمجة الشائعة للعقود الذكية مثل Solidity، تدعم لغة Rust العمليات الحسابية العشرية بشكل أصلي. ومع ذلك، توجد مشاكل دقيقة لا مفر منها في العمليات الحسابية العشرية. لذلك، لا يُنصح باستخدام العمليات الحسابية العشرية عند كتابة العقود الذكية، خاصة عند التعامل مع النسب أو أسعار الفائدة التي تتعلق بقرارات اقتصادية أو مالية هامة.
تتبع معظم لغات البرمجة الشائعة لتمثيل الأعداد العشرية القياسية IEEE 754، ولا يُستثنى من ذلك لغة Rust. يتم تخزين نوع الأعداد العشرية المزدوجة f64 داخل الكمبيوتر بشكل بيانات ثنائية.
تستخدم الأعداد العشرية صيغة العد العلمي ذات الأساس 2 للتعبير عنها. على سبيل المثال، يمكن استخدام عدد ثنائي محدود العدد 0.1101 لتمثيل العدد العشري 0.8125. ومع ذلك، بالنسبة للعدد العشري 0.7، ستظهر خلال عملية تحويله إلى عدد عشري ثنائي تمثيل دائري لا نهائي، مما يجعل من المستحيل تمثيله بدقة باستخدام عدد عشري محدود الطول، مما يؤدي إلى ظاهرة "التقريب".
افترض أنه يجب توزيع 0.7 من الرموز على عشرة مستخدمين، وسيتم حساب عدد الرموز التي يحصل عليها كل مستخدم وحفظها في المتغير result_0. بعد تنفيذ حالات الاختبار ذات الصلة، يمكننا أن نلاحظ أن قيمة amount لا تعبر بدقة عن 0.7، بل هي قيمة قريبة جدًا وهي 0.69999999999999995559. علاوة على ذلك، بالنسبة لعملية القسمة الفردية amount/divisor، ستصبح نتيجة العملية أيضًا غير دقيقة وهي 0.06999999999999999، وليس القيمة المتوقعة 0.07. ومن هنا، فإن عدم اليقين في عمليات الأعداد العشرية يتضح.
في هذا السياق، نحتاج إلى التفكير في استخدام أنواع أخرى من طرق تمثيل القيم العددية في العقود الذكية، مثل الأعداد العشرية الثابتة. في كتابة العقود الذكية الفعلية، عادة ما يتم استخدام كسر له مقام ثابت لتمثيل قيمة معينة، مثل الكسر x/N حيث N هو ثابت وx يمكن أن يتغير.
في بعض سلاسل الكتل العامة، القيمة الشائعة لـ N هي 10^24، أي أن 10^24 وحدة أصغر تعادل وحدة واحدة من الرمز الرئيسي. بناءً على ذلك، يمكننا تحويل العمليات العشرية إلى عمليات صحيحة للحصول على نتائج حسابية أكثر دقة.
!
2. مشكلة دقة حسابات الأعداد الصحيحة في Rust
يمكن استخدام العمليات الحسابية الصحيحة لحل مشكلة فقدان دقة العمليات الحسابية العائمة في بعض السيناريوهات. ولكن هذا لا يعني أن نتائج الحسابات الصحيحة دقيقة وموثوقة تمامًا. ومن الأسباب التي تؤثر على دقة الحسابات الصحيحة ما يلي:
2.1 ترتيب العمليات
إن تغيير ترتيب العمليات بين الضرب والقسمة، اللتين لهما نفس أولوية العمليات الحسابية، يمكن أن يؤثر مباشرة على نتائج الحساب، مما يؤدي إلى مشكلات دقة الحسابات الصحيحة. بالنسبة لقسمة الأعداد الصحيحة، سيتم تجاهل الدقة التي تكون أقل من المقسوم عليه. لذا، في بعض عمليات الحساب، قد يؤدي إجراء عملية القسمة أولاً إلى فقدان الدقة.
2.2 حجم كمي صغير جداً
عندما تكون القيم المعنية صغيرة جداً، قد تحدث مشاكل في الدقة في العمليات الحسابية الصحيحة. على سبيل المثال، في بعض الحالات، قد تعطي العمليات الحسابية الصحيحة المباشرة وعمليات الحساب بعد إدخال أعداد أكبر نتائج مختلفة.
!
3. كيفية كتابة العقود الذكية في Rust لتقييم القيم
لضمان دقة الحسابات في العقود الذكية، يمكن اتخاذ التدابير الوقائية التالية:
3.1 تعديل ترتيب العمليات الحسابية
حاول أن تفضل ضرب الأعداد الصحيحة على قسمة الأعداد الصحيحة.
3.2 زيادة مرتبة العدد الصحيح
استخدام مقاييس أكبر لتمثيل القيم، وخلق كميات أكبر للمشاركة في العمليات الحسابية، من أجل زيادة الدقة.
3.3 تراكم فقدان دقة العمليات
بالنسبة لمشكلة دقة حساب الأعداد الصحيحة التي لا يمكن تجنبها، يمكن النظر في تسجيل خسائر دقة العمليات التراكمية. في العمليات اللاحقة، يمكن أخذ هذه الخسائر في الاعتبار لتحقيق توزيع أكثر إنصافًا للنتائج.
3.4 استخدام مكتبة Rust Crate rust-decimal
تتناسب هذه المكتبة مع سيناريوهات الحسابات المالية العشرية التي تتطلب دقة عالية ولا تحتوي على أخطاء تقريب.
3.5 النظر في آلية التقريب
عند تصميم العقود الذكية، غالبًا ما تتبع مشكلة التقريب مبدأ "مفيد لنفسه، ضار بالآخرين". اختر طريقة التقريب المناسبة، سواء كانت التقريب لأسفل أو التقريب لأعلى أو أي طريقة تقريب أخرى حسب الحالة المحددة.
من خلال اتخاذ هذه التدابير، يمكن تحقيق حسابات عددية أكثر دقة في العقود الذكية بلغة Rust، وتجنب الأخطاء أو النتائج غير العادلة الناجمة عن مشاكل الدقة.
!
شاهد النسخة الأصلية
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
تقنيات حساب الأعداد في العقود الذكية بلغة Rust: تجنب فخ الأعداد العشرية
Rust العقود الذكية养成日记(7)数值精算
1. مشكلة دقة العمليات العشرية
على عكس لغات البرمجة الشائعة للعقود الذكية مثل Solidity، تدعم لغة Rust العمليات الحسابية العشرية بشكل أصلي. ومع ذلك، توجد مشاكل دقيقة لا مفر منها في العمليات الحسابية العشرية. لذلك، لا يُنصح باستخدام العمليات الحسابية العشرية عند كتابة العقود الذكية، خاصة عند التعامل مع النسب أو أسعار الفائدة التي تتعلق بقرارات اقتصادية أو مالية هامة.
تتبع معظم لغات البرمجة الشائعة لتمثيل الأعداد العشرية القياسية IEEE 754، ولا يُستثنى من ذلك لغة Rust. يتم تخزين نوع الأعداد العشرية المزدوجة f64 داخل الكمبيوتر بشكل بيانات ثنائية.
تستخدم الأعداد العشرية صيغة العد العلمي ذات الأساس 2 للتعبير عنها. على سبيل المثال، يمكن استخدام عدد ثنائي محدود العدد 0.1101 لتمثيل العدد العشري 0.8125. ومع ذلك، بالنسبة للعدد العشري 0.7، ستظهر خلال عملية تحويله إلى عدد عشري ثنائي تمثيل دائري لا نهائي، مما يجعل من المستحيل تمثيله بدقة باستخدام عدد عشري محدود الطول، مما يؤدي إلى ظاهرة "التقريب".
افترض أنه يجب توزيع 0.7 من الرموز على عشرة مستخدمين، وسيتم حساب عدد الرموز التي يحصل عليها كل مستخدم وحفظها في المتغير result_0. بعد تنفيذ حالات الاختبار ذات الصلة، يمكننا أن نلاحظ أن قيمة amount لا تعبر بدقة عن 0.7، بل هي قيمة قريبة جدًا وهي 0.69999999999999995559. علاوة على ذلك، بالنسبة لعملية القسمة الفردية amount/divisor، ستصبح نتيجة العملية أيضًا غير دقيقة وهي 0.06999999999999999، وليس القيمة المتوقعة 0.07. ومن هنا، فإن عدم اليقين في عمليات الأعداد العشرية يتضح.
في هذا السياق، نحتاج إلى التفكير في استخدام أنواع أخرى من طرق تمثيل القيم العددية في العقود الذكية، مثل الأعداد العشرية الثابتة. في كتابة العقود الذكية الفعلية، عادة ما يتم استخدام كسر له مقام ثابت لتمثيل قيمة معينة، مثل الكسر x/N حيث N هو ثابت وx يمكن أن يتغير.
في بعض سلاسل الكتل العامة، القيمة الشائعة لـ N هي 10^24، أي أن 10^24 وحدة أصغر تعادل وحدة واحدة من الرمز الرئيسي. بناءً على ذلك، يمكننا تحويل العمليات العشرية إلى عمليات صحيحة للحصول على نتائج حسابية أكثر دقة.
!
2. مشكلة دقة حسابات الأعداد الصحيحة في Rust
يمكن استخدام العمليات الحسابية الصحيحة لحل مشكلة فقدان دقة العمليات الحسابية العائمة في بعض السيناريوهات. ولكن هذا لا يعني أن نتائج الحسابات الصحيحة دقيقة وموثوقة تمامًا. ومن الأسباب التي تؤثر على دقة الحسابات الصحيحة ما يلي:
2.1 ترتيب العمليات
إن تغيير ترتيب العمليات بين الضرب والقسمة، اللتين لهما نفس أولوية العمليات الحسابية، يمكن أن يؤثر مباشرة على نتائج الحساب، مما يؤدي إلى مشكلات دقة الحسابات الصحيحة. بالنسبة لقسمة الأعداد الصحيحة، سيتم تجاهل الدقة التي تكون أقل من المقسوم عليه. لذا، في بعض عمليات الحساب، قد يؤدي إجراء عملية القسمة أولاً إلى فقدان الدقة.
2.2 حجم كمي صغير جداً
عندما تكون القيم المعنية صغيرة جداً، قد تحدث مشاكل في الدقة في العمليات الحسابية الصحيحة. على سبيل المثال، في بعض الحالات، قد تعطي العمليات الحسابية الصحيحة المباشرة وعمليات الحساب بعد إدخال أعداد أكبر نتائج مختلفة.
!
3. كيفية كتابة العقود الذكية في Rust لتقييم القيم
لضمان دقة الحسابات في العقود الذكية، يمكن اتخاذ التدابير الوقائية التالية:
3.1 تعديل ترتيب العمليات الحسابية
حاول أن تفضل ضرب الأعداد الصحيحة على قسمة الأعداد الصحيحة.
3.2 زيادة مرتبة العدد الصحيح
استخدام مقاييس أكبر لتمثيل القيم، وخلق كميات أكبر للمشاركة في العمليات الحسابية، من أجل زيادة الدقة.
3.3 تراكم فقدان دقة العمليات
بالنسبة لمشكلة دقة حساب الأعداد الصحيحة التي لا يمكن تجنبها، يمكن النظر في تسجيل خسائر دقة العمليات التراكمية. في العمليات اللاحقة، يمكن أخذ هذه الخسائر في الاعتبار لتحقيق توزيع أكثر إنصافًا للنتائج.
3.4 استخدام مكتبة Rust Crate rust-decimal
تتناسب هذه المكتبة مع سيناريوهات الحسابات المالية العشرية التي تتطلب دقة عالية ولا تحتوي على أخطاء تقريب.
3.5 النظر في آلية التقريب
عند تصميم العقود الذكية، غالبًا ما تتبع مشكلة التقريب مبدأ "مفيد لنفسه، ضار بالآخرين". اختر طريقة التقريب المناسبة، سواء كانت التقريب لأسفل أو التقريب لأعلى أو أي طريقة تقريب أخرى حسب الحالة المحددة.
من خلال اتخاذ هذه التدابير، يمكن تحقيق حسابات عددية أكثر دقة في العقود الذكية بلغة Rust، وتجنب الأخطاء أو النتائج غير العادلة الناجمة عن مشاكل الدقة.
!