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:

  1. Terdapat cacat dalam logika kontrak yang menyebabkan kompleksitas perhitungan terlalu tinggi, menyebabkan konsumsi Gas melebihi batas.

  2. Saat memanggil lintas kontrak, eksekusi kontrak bergantung pada status kontrak eksternal yang tidak dapat diandalkan, yang mengakibatkan pemblokiran.

  3. 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");

untuk cur_account di self.registered.iter() {
    let saldo = self.accounts.get(&cur_account).expect("ERR_GET");
    self.accounts.insert(&cur_account, &balance.checked_add(amount).expect("ERR_ADD" ));
    log!("Coba distribusikan ke akun {}", &cur_account);
    
    ext_ft_token::ft_transfer(
        cur_account.clone(),
        jumlah,
        &FTTOKEN,
        0,
        GAS_FOR_SINGLE_CALL  
    );
}

}

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

self.accounts.insert(&account_id, &0);

ext_ft_token::ft_transfer(
    account_id,
    jumlah 
    &FTTOKEN,
    0,
    GAS_FOR_SINGLE_CALL
);

}

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

jika self.current_leader == DEFAULT_ACCOUNT {
    self.current_leader = sender_id;
    self.highest_bid = jumlah;
} else {
    ext_ft_token::account_exist(
        self.current_leader.clone)(,
        &FTTOKEN,
        0,
        env::prepaid_gas() - GAS_FOR_SINGLE_CALL * 4,
    (.then)ext_self::account_resolve)
        sender_id,
        jumlah
        &env::current_account_id((,
        0,
        GAS_FOR_SINGLE_CALL * 3,
    ();
}

log!)
    "current_leader: {} highest_bid: {}",
    self.current_leader,
    self.highest_bid
);

PromiseOrValue::Value(0)

}

#( 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");

self.lost_funds.remove(&account_id);

ext_ft_token::ft_transfer(
    account_id,
    jumlah,
    &FTTOKEN,
    0,
    GAS_FOR_SINGLE_CALL
);

}

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,>

Lihat Asli
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.
  • Hadiah
  • 7
  • Bagikan
Komentar
0/400
ConsensusDissentervip
· 07-19 04:59
wawasan berharga值得收藏学习
Lihat AsliBalas0
MEVHunterZhangvip
· 07-18 23:52
Tidak salah lagi, itu adalah pengalaman yang berharga.
Lihat AsliBalas0
PumpBeforeRugvip
· 07-18 15:28
Siapa yang membayar biaya Gas, mari kita ketahui.
Lihat AsliBalas0
GmGnSleepervip
· 07-17 00:43
Keamanan adalah yang utama.
Lihat AsliBalas0
ImpermanentPhilosophervip
· 07-17 00:41
Cukup restart paksa.
Lihat AsliBalas0
GasFeePhobiavip
· 07-17 00:23
Biaya gas adalah masalah besar
Lihat AsliBalas0
AllInAlicevip
· 07-17 00:21
Optimalisasi gas itu penting
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)