Rust hợp đồng thông minh số liệu tính toán: Hướng dẫn tránh cạm bẫy và thực tiễn tốt nhất

Tính toán số học trong hợp đồng thông minh Rust

Trong lập trình hợp đồng thông minh, vấn đề độ chính xác của phép toán số là rất quan trọng. Bài viết này sẽ khám phá các vấn đề tính toán số phổ biến trong hợp đồng thông minh Rust và các giải pháp.

1. Vấn đề độ chính xác trong phép toán số thực

Ngôn ngữ Rust hỗ trợ tính toán số thực một cách tự nhiên, nhưng có vấn đề về độ chính xác không thể tránh khỏi trong tính toán số thực. Khi xử lý các tỷ lệ hoặc lãi suất liên quan đến quyết định kinh tế/tài chính quan trọng, không nên sử dụng tính toán số thực.

Loại số thực độ chính xác gấp đôi f64 trong ngôn ngữ Rust tuân theo tiêu chuẩn IEEE 754, sử dụng ký hiệu khoa học với cơ số 2. Một số số thập phân ( như 0.7) không thể được biểu diễn chính xác bằng số thực có số lượng bit hữu hạn, sẽ tồn tại hiện tượng "làm tròn".

Ví dụ, khi phân phát 0.7 token NEAR cho 10 người dùng trên chuỗi công khai NEAR:

gỉ let amount: f64 = 0.7;
let divisor: f64 = 10.0;
let result_0 = amount / divisor;

giá trị thực tế của amount là 0.69999999999999995559, kết quả của result_0 là 0.06999999999999999, không phải là 0.07 như đã dự kiến.

Để giải quyết vấn đề này, có thể xem xét việc sử dụng phương pháp biểu diễn số cố định. Trong NEAR Protocol, thường sử dụng 10^24 làm mẫu số, tức là 1 NEAR = 10^24 yoctoNEAR. Cách tính toán đã được sửa đổi như sau:

gỉ 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;

Cách này có thể đạt được kết quả tính toán chính xác: 0.7 NEAR / 10 = 0.07 NEAR.

2. Vấn đề độ chính xác trong tính toán số nguyên Rust

Việc sử dụng số nguyên để tính toán mặc dù có thể giải quyết một số vấn đề về độ chính xác của số thực trong một số tình huống, nhưng vẫn tồn tại một số yếu tố ảnh hưởng đến độ chính xác của phép tính.

2.1 Thứ tự thực hiện

Thứ tự trước và sau của phép nhân và phép chia cùng cấp độ ưu tiên toán học có thể ảnh hưởng trực tiếp đến kết quả tính toán. Ví dụ:

rỉ sét 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");

Kết quả của result_0 và result_1 khác nhau, nguyên nhân là do phép chia số nguyên sẽ bỏ qua độ chính xác nhỏ hơn số chia.

2.2 quy mô quá nhỏ

Khi liên quan đến các phép tính ở quy mô nhỏ hơn, cũng có thể dẫn đến vấn đề về độ chính xác:

gỉ 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");

Kết quả của result_0 và result_1 khác nhau, và result_1 gần với giá trị kỳ vọng thực tế hơn.

3. Làm thế nào để viết hợp đồng thông minh Rust cho tính toán số

Để nâng cao độ chính xác của phép toán số trong hợp đồng thông minh Rust, có thể thực hiện các biện pháp sau:

3.1 Điều chỉnh thứ tự thực hiện phép toán

Hãy để phép nhân số nguyên ưu tiên hơn phép chia số nguyên.

3.2 Tăng cường độ lớn của số nguyên

Sử dụng quy mô lớn hơn để tạo ra các phân tử lớn hơn, cải thiện độ chính xác của phép toán.

3.3 Tích lũy tổn thất độ chính xác tính toán

Đối với vấn đề độ chính xác của phép tính số nguyên không thể tránh khỏi, có thể xem xét việc ghi lại tổn thất độ chính xác tích lũy. Ví dụ:

gỉ 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 }

Phương pháp này có thể dần dần bù đắp cho sự mất mát độ chính xác trong nhiều vòng phân phối.

( 3.4 Sử dụng thư viện Rust Crate rust-decimal

Thư viện này phù hợp cho các phép toán tài chính với số thập phân cần tính toán chính xác và không có sai số làm tròn.

) 3.5 Xem xét cơ chế làm tròn

Trong thiết kế hợp đồng thông minh, vấn đề làm tròn thường tuân theo nguyên tắc "Tôi muốn thu lợi, người khác không được lợi dụng tôi". Chọn làm tròn xuống, làm tròn lên hoặc làm tròn thông thường tùy theo tình huống.

Bằng cách áp dụng những phương pháp này, có thể nâng cao đáng kể độ chính xác và độ tin cậy của phép tính số trong hợp đồng thông minh Rust.

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

Xem bản gốc
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.
  • Phần thưởng
  • 3
  • Chia sẻ
Bình luận
0/400
MaticHoleFillervip
· 17giờ trước
Cả ngày mắc kẹt trong vấn đề độ chính xác, đau lòng mất trắng.
Xem bản gốcTrả lời0
StablecoinAnxietyvip
· 17giờ trước
Lại cần thuật toán lại cần tài chính, hơi đau đầu~
Xem bản gốcTrả lời0
GhostAddressMinervip
· 18giờ trước
Một ví dụ điển hình về việc đổ lỗi cho tiêu chuẩn trong vấn đề độ chính xác, không biết đã rút tiền bao nhiêu trong bóng tối, dữ liệu on-chain sẽ không nói dối.
Xem bản gốcTrả lời0
  • Ghim
Giao dịch tiền điện tử mọi lúc mọi nơi
qrCode
Quét để tải xuống ứng dụng Gate
Cộng đồng
Tiếng Việt
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)