Rust akıllı sözleşmeler tamsayı hesaplama hassasiyeti sorunu ve çözüm önerileri

Rust akıllı sözleşmeler yetiştirme günlüğü (: Tam sayı hesaplama hassasiyeti sorunu

Geçmiş değerlendirmesi:

  • Rust akıllı sözleşmeler yetiştirme günlüğü )1( sözleşme durumu veri tanımı ve yöntem uygulaması
  • Rust akıllı sözleşmeler yetiştirme günlüğü ) 2( yazma Rust akıllı sözleşmeler birim testi
  • Rust akıllı sözleşmeler yetiştirme günlüğü )3( Rust akıllı sözleşme dağıtımı, fonksiyon çağrısı ve Explorer kullanımı
  • Rust akıllı sözleşmeler yetiştirme günlükleri ) 4( Rust akıllı sözleşmeler tam sayı taşması
  • Rust akıllı sözleşmeler yetiştirme günlüğü )5( reentrancy saldırısı
  • Rust akıllı sözleşmeler yetiştirme günlüğü )6( hizmet reddi saldırısı

1. Ondalık sayıların hesaplama hassasiyeti sorunu

Solidity'den farklı olarak, Rust yerel olarak ondalık sayı işlemlerini destekler. Ancak, ondalık sayı işlemlerinin kaçınılmaz hassasiyet sorunları vardır, bu nedenle özellikle önemli ekonomik/finansal kararların oranları veya faiz oranlarıyla ilgili olarak akıllı sözleşmelerde kullanılması önerilmez.

Rust, IEEE 754 standardını izleyerek kayan noktalı sayıları temsil eder. f64 çift hassasiyetli kayan nokta türü, bilgisayar içinde ikili bilimsel gösterim kullanılarak temsil edilir.

Bazı ondalık sayılar, sınırlı basamaklı ikili sayı sistemiyle tam olarak temsil edilebilir; örneğin 0.8125, 0.1101 olarak ifade edilebilir. Ancak 0.7 gibi ondalık sayılar, sonsuz döngüsel ikili temsil üretir ve sınırlı basamaklı kayan nokta sayılarıyla tam olarak gösterilemez, bu da "yuvarlama" sorununu doğurur.

NEAR kamu zincirinde 10 kullanıcıya 0.7 NEAR token dağıtma örneği:

pas #) fn precision_test_float[test]( { let amount: f64 = 0.7;
let divisor: f64 = 10.0;
let result_0 = amount / divisor;
println!)"Miktarın değeri: {:.20}", amount(; assert_eq!)result_0, 0.07(; }

Çalışma sonucu, amount'un gerçek değerinin 0.69999999999999995559, result_0'ın ise 0.06999999999999999 olduğunu, beklenen 0.07'ye eşit olmadığını gösteriyor.

Bu sorunu çözmek için, sabit noktalı sayılar kullanılabilir. NEAR'da, genellikle 1 NEAR token'ı 10^24 yoctoNEAR olarak ifade edilir. Değiştirilen kod:

pas #) fn precision_test_integer[test]( { let N: u128 = 1_000_000_000_000_000_000_000_000;
let amount: u128 = 700_000_000_000_000_000_000_000; let divisor: u128 = 10;
let result_0 = amount / divisor; assert_eq!)result_0, 70_000_000_000_000_000_000_000(; }

Böylece tam bir sonuç elde edilebilir: 0.7 NEAR / 10 = 0.07 NEAR.

2. Rust tam sayı hesaplama hassasiyeti sorunu

Tam sayı işlemleri bazı durumlarda kayan nokta hassasiyet sorunlarını çözebilirken, tam sayı hesaplamalarının da hassasiyet sorunları bulunmaktadır.

) 2.1 İşlem Sırası

Aynı seviyedeki çarpma ve bölme işlemlerinde, sıralamanın sonucu etkileyebileceği.

pas

fn precision_test_div_before_mul[test]( { let a: u128 = 1_0000; let b: u128 = 10_0000; let c: u128 = 20;

let result_0 = a.checked_mul)c(.unwrap)(.checked_div)b(.unwrap)(;
let result_1 = a.checked_div)b(.unwrap)(.checked_mul)c(.unwrap)(;

assert_eq!)result_0,result_1(;

}

Sonuçlar gösteriyor result_0 = 2, result_1 = 0.

Sebep, tam sayı bölmesinin bölenin altındaki hassasiyeti atmasıdır. result_1'i hesaplarken, )a / b( önce hassasiyeti kaybedip 0 olur; oysa result_0 önce )a * c( hesaplayarak hassasiyet kaybını önlemiştir.

) 2.2 çok küçük bir ölçek

pas

fn precision_test_decimals[test]( { let a: u128 = 10; let b: u128 = 3; let c: u128 = 4; let decimal: u128 = 100_0000;

let result_0 = a.checked_div)b(.unwrap)(.checked_mul)c(.unwrap)(;

let result_1 = a.checked_mul)decimal(.unwrap)(
                .checked_div)b(.unwrap)(
                .checked_mul)c(.unwrap)(
                .checked_div)decimal(.unwrap)(;

println!)"{}:{}", result_0, result_1(;
assert_eq!)result_0, result_1(;

}

Sonuçlar gösteriyor ki result_0 = 12, result_1 = 13, ve ikincisi gerçek değer 13.3333'e daha yakın.

![])https://img-cdn.gateio.im/webp-social/moments-7bdd27c1211e1cc345bf262666a993da.webp(

3. Sayısal Aktüeryal Rust akıllı sözleşmeler nasıl yazılır

Hassasiyeti artırmak için aşağıdaki önlemler alınabilir:

) 3.1 İşlem sırasını ayarlama

Tam sayılar çarpımının bölmeden önce gelmesini sağlayın.

3.2 Tam sayıların büyüklüğünü artırma

Daha büyük bir ölçek kullanarak, daha büyük moleküller oluşturun. Örneğin, 1 NEAR = 10^24 yoctoNEAR olarak tanımlanır.

3.3 Birikim hesaplama doğruluğunun kaybı

Kayıt ve biriken hassasiyet kaybını düzeltmek için sonraki işlemlerde telafi et:

pas const USER_NUM: u128 = 3;

u128 { let token_to_distribute = offset + amount; let per_user_share = token_to_distribute / USER_NUM; let recorded_offset = token_to_distribute - per_user_share * USER_NUM; kayıtlı_ofset }

fn record_offset_test() { let mut offset: u128 = 0; for i in 1..7 { offset = distribute[test]10_000_000_000_000_000_000_000_000, offset(; } }

![])https://img-cdn.gateio.im/webp-social/moments-1933a4a2dd723a847f0059d31d1780d1.webp(

) 3.4 Rust Crate kütüphanesi rust-decimal kullanımı

Bu kütüphane, yüksek hassasiyet gerektiren ve yuvarlama hatası olmayan ondalık finansal hesaplamalar için uygundur.

( 3.5 Yuvarlama mekanizmasını dikkate alın

Akıllı sözleşmeler tasarımında, yuvarlama genellikle "bana faydalı" ilkesini takip eder: Aşağı yuvarlamak bana faydalıysa aşağı, yukarı yuvarlamak bana faydalıysa yukarı, nadiren dört işlem kuralı uygulanır.

![])https://img-cdn.gateio.im/webp-social/moments-6e8b4081214a69423fc7ae022d05c728.webp###

EQ0.82%
View Original
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • Reward
  • 8
  • Share
Comment
0/400
LostBetweenChainsvip
· 07-25 17:53
Tam sayı hesaplamalarını bile yapamıyor, hangi sözleşmeyi oynayacak?
View OriginalReply0
WagmiWarriorvip
· 07-25 11:45
7. makaleyi gördüm, çok ince.
View OriginalReply0
MetaMisfitvip
· 07-25 01:13
Rust bu akıllı sözleşmelerde çok fazla sorun var gibi.
View OriginalReply0
DuckFluffvip
· 07-22 22:44
Aman Tanrım, float sayılar yine bir iş çıkarıyor~
View OriginalReply0
MaticHoleFillervip
· 07-22 22:44
Hassasiyet tuzağına düşenler burada deneyimlerini paylaşıyor!
View OriginalReply0
MetadataExplorervip
· 07-22 22:44
Tam sayılar genellikle göz ardı ediliyor, oldukça kritik.
View OriginalReply0
MEVHuntervip
· 07-22 22:29
kesinlik bir mev honeypot... floatlarını sıkı tut yoksa rekt olursun ser
View OriginalReply0
TrustlessMaximalistvip
· 07-22 22:16
Bu kayan nokta işlemlerinden kaçınılması gereken bir tuzak!
View OriginalReply0
Trade Crypto Anywhere Anytime
qrCode
Scan to download Gate app
Community
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)