Perhitungan nilai kontrak pintar Rust: Panduan menghindari kesalahan dan praktik terbaik

Perhitungan Presisi Numerik dalam Smart Contract Rust

Dalam pemrograman smart contract, masalah presisi perhitungan numerik sangat penting. Artikel ini akan membahas masalah akuntansi numerik yang umum dalam smart contract Rust dan solusi yang ada.

1. Masalah presisi dalam perhitungan angka desimal

Bahasa Rust secara native mendukung operasi bilangan pecahan, tetapi operasi bilangan pecahan memiliki masalah presisi perhitungan yang tidak dapat dihindari. Saat menangani rasio atau suku bunga yang melibatkan keputusan ekonomi/keuangan penting, tidak disarankan untuk menggunakan operasi bilangan pecahan.

Tipe floating point ganda f64 dalam bahasa Rust mengikuti standar IEEE 754, menggunakan notasi ilmiah dengan basis 2. Beberapa desimal ( seperti 0.7) tidak dapat direpresentasikan secara akurat dengan bilangan floating point dengan panjang terbatas, yang akan mengakibatkan fenomena "pembulatan".

Misalnya, saat mendistribusikan 0.7 token NEAR kepada 10 pengguna di blockchain NEAR:

karat let amount: f64 = 0.7;
let divisor: f64 = 10.0; let result_0 = amount / divisor;

nilai aktual dari amount adalah 0.69999999999999995559, hasil dari result_0 adalah 0.06999999999999999, bukan 0.07 seperti yang diharapkan.

Untuk menyelesaikan masalah ini, Anda dapat mempertimbangkan menggunakan representasi bilangan tetap. Di NEAR Protocol, biasanya menggunakan 10^24 sebagai penyebut, yaitu 1 NEAR = 10^24 yoctoNEAR. Cara perhitungan yang dimodifikasi adalah sebagai berikut:

karat 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;

Dengan cara ini, Anda dapat memperoleh hasil perhitungan yang akurat: 0,7 NEAR / 10 = 0,07 NEAR.

2. Masalah Presisi Perhitungan Integer Rust

Meskipun menggunakan perhitungan bilangan bulat dapat menyelesaikan masalah presisi bilangan pecahan dalam beberapa skenario, masih ada beberapa faktor yang mempengaruhi ketepatan perhitungan.

2.1 Urutan Operasi

Urutan perubahan antara perkalian dan pembagian dengan prioritas aritmatika yang sama dapat langsung mempengaruhi hasil perhitungan. Contohnya:

karat let a: u128 = 1_0000; let b: u128 = 10_0000; let c: u128 = 20;

// result_0 = a * c / b let result_0 = a.checked_mul(c).expect("ERR_MUL").checked_div(b).expect("ERR_DIV");

// result_1 = a / b * c let result_1 = a.checked_div(b).expect("ERR_DIV").checked_mul(c).expect("ERR_MUL");

Hasil dari result_0 dan result_1 berbeda, alasannya adalah bahwa pembagian bilangan bulat akan mengabaikan presisi yang lebih kecil dari pembagi.

2.2 skala yang terlalu kecil

Ketika melibatkan perhitungan dalam skala yang lebih kecil, juga dapat menyebabkan masalah akurasi:

karat let a: u128 = 10; let b: u128 = 3; let c: u128 = 4; let decimal: u128 = 100_0000;

// result_0 = (a / b) * c let result_0 = a.checked_div(b).expect("ERR_DIV").checked_mul(c).expect("ERR_MUL");

// result_1 = (a * decimal / b) * c / decimal; let result_1 = a.checked_mul(decimal).expect("ERR_MUL") .checked_div(b).expect("ERR_DIV") .checked_mul(c).expect("ERR_MUL") .checked_div(decimal).expect("ERR_DIV");

Hasil operasi result_0 dan result_1 berbeda, dan result_1 lebih mendekati nilai harapan yang sebenarnya.

3. Bagaimana Menulis Kontrak Pintar Rust untuk Aktuaria Numerik

Untuk meningkatkan akurasi perhitungan numerik dalam smart contract Rust, langkah-langkah berikut dapat diambil:

3.1 Menyesuaikan urutan operasi perhitungan

Biarkan perkalian bilangan bulat diutamakan dibandingkan pembagian bilangan bulat.

3.2 Menambah Besaran Bilangan Bulat

Gunakan skala yang lebih besar untuk menciptakan molekul yang lebih besar, meningkatkan akurasi perhitungan.

3.3 Kerugian presisi akumulasi operasi

Untuk masalah presisi perhitungan integer yang tidak dapat dihindari, Anda dapat mempertimbangkan untuk mencatat akumulasi kehilangan presisi perhitungan. Misalnya:

karat 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; recorded_offset }

Metode ini dapat secara bertahap mengkompensasi kehilangan akurasi dalam distribusi multi-putaran.

( 3.4 Menggunakan pustaka Rust Crate rust-decimal

Perpustakaan ini cocok untuk perhitungan keuangan desimal yang memerlukan akurasi tinggi dan tidak memiliki kesalahan pembulatan.

) 3.5 Mempertimbangkan mekanisme pembulatan

Dalam merancang smart contract, masalah pembulatan biasanya mengikuti prinsip "Saya ingin mengambil keuntungan, orang lain tidak boleh mengambil keuntungan dari saya". Pilih untuk membulatkan ke bawah, membulatkan ke atas, atau membulatkan sesuai kebutuhan.

Dengan mengadopsi metode ini, akurasi dan keandalan perhitungan numerik dalam kontrak pintar Rust dapat meningkat secara signifikan.

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

Lihat Asli
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.
  • Hadiah
  • 3
  • Bagikan
Komentar
0/400
MaticHoleFillervip
· 10jam yang lalu
Sepanjang hari terjebak dalam masalah presisi, kehilangan usaha percuma.
Lihat AsliBalas0
StablecoinAnxietyvip
· 10jam yang lalu
Sedikit pusing karena harus mengurus algoritme dan keuangan~
Lihat AsliBalas0
GhostAddressMinervip
· 11jam yang lalu
Satu lagi kasus klasik pengalihan masalah presisi kepada standar, secara diam-diam tidak tahu berapa banyak dana yang telah dicairkan, data on-chain tidak akan berbohong.
Lihat AsliBalas0
  • Sematkan
Perdagangkan Kripto Di Mana Saja Kapan Saja
qrCode
Pindai untuk mengunduh aplikasi Gate
Komunitas
Bahasa Indonesia
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)