Jika akun penawar sebelumnya dihancurkan, penawaran baru akan diblokir.
Perlu mempertimbangkan situasi di mana panggilan eksternal gagal, dapat menyimpan token yang tidak dapat dikembalikan untuk diambil oleh pengguna di kemudian hari:
karat
pub fn withdraw_lost_funds(&mut self) {
let account_id = env::predecessor_account_id();
let amount = self.lost_funds.get(&account_id).expect("Tidak ada dana yang hilang");
Halaman ini mungkin berisi konten pihak ketiga, yang disediakan untuk tujuan informasi saja (bukan pernyataan/jaminan) dan tidak boleh dianggap sebagai dukungan terhadap pandangannya oleh Gate, atau sebagai nasihat keuangan atau profesional. Lihat Penafian untuk detailnya.
23 Suka
Hadiah
23
7
Bagikan
Komentar
0/400
ConsensusDissenter
· 07-19 04:59
wawasan berharga值得收藏学习
Lihat AsliBalas0
MEVHunterZhang
· 07-18 23:52
Tidak salah lagi, itu adalah pengalaman yang berharga.
Panduan praktis untuk bertahan dari serangan DoS pada kontrak pintar Rust
Serangan penolakan layanan dalam kontrak pintar Rust
Serangan penolakan (DoS) of-service dapat membuat kontrak pintar tidak dapat digunakan untuk jangka waktu tertentu. Ada beberapa alasan untuk ini:
Terdapat cacat dalam logika kontrak yang menyebabkan kompleksitas perhitungan terlalu tinggi, menyebabkan konsumsi Gas melebihi batas.
Saat memanggil lintas kontrak, eksekusi kontrak bergantung pada status kontrak eksternal yang tidak dapat diandalkan, yang mengakibatkan pemblokiran.
Pemilik kontrak kehilangan kunci privat, mengakibatkan ketidakmampuan untuk menjalankan fungsi istimewa utama.
Berikut ini adalah analisis kerentanan DoS ini dengan contoh spesifik.
1. Menelusuri struktur data besar yang dapat diubah dari luar
Berikut ini adalah kontrak "dividen" sederhana dengan risiko DoS:
karat #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub terdaftar: Vec, pub accounts: UnorderedMap<accountid, balance="">, }
pub fn register_account(&mut self) { if self.accounts.insert(&env::p redecessor_account_id(), &0).is_ some() { env::panic("Akun sudah terdaftar".to_string().as_bytes()); } else { self.registered.push(env::predecessor_account_id()); } log!("Akun terdaftar {}", env::predecessor_account_id()); }
pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(), DISTRIBUTOR, "ERR_NOT_ALLOWED");
}
Di sini self.registered dapat diperluas tanpa batas, yang mengakibatkan kekurangan Gas saat iterasi.
Model "penarikan" harus digunakan sebagai gantinya, memungkinkan pengguna untuk secara aktif menarik hadiah:
karat pub fn withdraw(&mut self) { biarkan account_id = env::p redecessor_account_id(); let amount = self.accounts.get(&account_id).expect("No reward");
}
2. Ketergantungan status antar kontrak menyebabkan kebuntuan
Berikut adalah sebuah kontrak "lelang":
karat #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub terdaftar: Vec, pub bid_price: UnorderedMap\u003caccountid, balance=""\u003e, pub current_leader: AccountId, highest_bid Pub: U128, pub refund: bool }
PromiseOrValue { assert!(jumlah > self.highest_bid);
}
#( pub fn account_resolve)&mut self, sender_id: AccountId, amount: u128[private] { match env::promise_result(0) { PromiseResult::NotReady => tidak dapat dijangkau!(), PromiseResult::Successful(_) => { ext_ft_token::ft_transfer( self.current_leader.clone)(, self.highest_bid, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, (; self.current_leader = sender_id; self.highest_bid = jumlah; } PromiseResult::Failed => { ext_ft_token::ft_transfer) sender_id.klon)(, jumlah, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, (; log!)"Return Back Now"); } }; }
Jika akun penawar sebelumnya dihancurkan, penawaran baru akan diblokir.
Perlu mempertimbangkan situasi di mana panggilan eksternal gagal, dapat menyimpan token yang tidak dapat dikembalikan untuk diambil oleh pengguna di kemudian hari:
karat pub fn withdraw_lost_funds(&mut self) { let account_id = env::predecessor_account_id(); let amount = self.lost_funds.get(&account_id).expect("Tidak ada dana yang hilang");
}
3. Kunci pribadi pemilik hilang
Beberapa fungsi utama hanya dapat dipanggil oleh pemilik kontrak. Jika pemilik kehilangan kunci privat, fungsi-fungsi ini tidak akan dijalankan.
Skema multi-tanda tangan harus digunakan untuk mengelola kontrak untuk menghindari satu titik kegagalan:
karat pub struct MultiSigContract { pemilik: Vec, required_confirmations: u32, }
pub fn submit_transaction(&mut self, transaction: Transaction) { tegas!(self.owners.contains)&env::p redecessor_account_ id(((); // Tambahkan transaksi ke daftar tunggu konfirmasi }
pub fn confirm_transaction)&mut self, transaction_id: u64) { tegas!(self.owners.contains)&env::p redecessor_account_ id(((); // Tambah jumlah konfirmasi Jika jumlah konfirmasi yang diperlukan tercapai, transaksi dieksekusi }
Dengan metode di atas, risiko serangan DoS dalam smart contract dapat dicegah secara efektif.
! [])https://img-cdn.gateio.im/webp-social/moments-7076cf1226a2276d1e4cd994d259841f.webp)</accountid,></accountid,>