Rustスマートコントラクト防御DoS攻撃実戦ガイド

Rustスマートコントラクト中的サービス拒否攻撃

サービス拒否(DoS)攻撃はスマートコントラクトを一定期間正常に使用できなくします。主に以下のような理由があります:

  1. コントラクトのロジックに計算の複雑さに関する欠陥が存在し、Gasの消費が制限を超えています。

  2. クロスコントラクト呼び出し時、コントラクトの実行は信頼できない外部コントラクトの状態に依存し、ブロックが発生します。

  3. 契約所有者が秘密鍵を紛失したため、鍵の特権機能を実行できなくなります。

以下の具体例を通じて、これらのサービス拒否攻撃の脆弱性を分析します。

1. 外部から変更可能な大規模データ構造を遍歴する

以下はシンプルな"分配"スマートコントラクトで、DoSリスクがあります:

錆 #[near_bindgen] #[derive(BorshDeserialize、BorshSerialize)] pub struct コントラクト { パブ登録:Vec、 パブアカウント: UnorderedMap<accountid, balance="">, }

pub fn register_account(&mut self) { self.accounts.insert(&env::p redecessor_account_id()、&0).is_の場合 some() { env::panic("アカウントはすでに登録されています".to_string().as_bytes()); } else { self.registered.push(env::p redecessor_account_id()); } log!("登録済みアカウント {}", env::p redecessor_account_id()); }

pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::p redecessor_account_id(), ディストリビューター, "ERR_NOT_ALLOWED");

for cur_account in self.registered.iter() {
    バランス= self.accounts.get(&cur_account).expect("ERR_GET");
    self.accounts.insert(&cur_account, &balance.checked_add(amount).expect("ERR_ADD" ));
    log!("アカウント {} に配布してみてください", &cur_account);
    
    ext_ft_token::ft_transfer(
        cur_account.clone()、
        量
        &FTTOKENや
        0,
        GAS_FOR_SINGLE_CALL  
    );
}

}

ここでは、self.registeredを無期限に拡張できるため、トラバーサル中にガスが不足する可能性があります。

"引き出し"モードに変更し、ユーザーが報酬を積極的に引き出すようにするべきです:

錆 pub fn withdraw(&mut self) { let account_id = env::p redecessor_account_id(); let amount = self.accounts.get(&account_id).expect("報酬なし");

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

ext_ft_token::ft_transfer(
    account_id、
    量 
    &FTTOKENや
    0,
    シングルコール用GAS
);

}

2. クロスコントラクト状態の依存関係はブロッキングにつながります

以下は"入札"スマートコントラクトです:

錆 #[near_bindgen] #[derive(BorshDeserialize、BorshSerialize)] pub struct コントラクト { パブ登録:Vec、 pub bid_price: UnorderedMap<accountid, balance="">, 公開current_leader: AccountId, パブhighest_bid:U128、 パブの払い戻し:ブール }

pub fn bid(&mut self, sender_id: AccountId, amount: u128) -> PromiseOrValue { アサート!(amount > self.highest_bid);

if self.current_leader == DEFAULT_ACCOUNT {
    self.current_leader = sender_id;
    self.highest_bid = 金額;
} else {
    ext_ft_token::account_exist(
        self.current_leader.clone()、
        &FTTOKENや
        0,
        env::p repaid_gas() - GAS_FOR_SINGLE_CALL * 4、
    ).then(ext_self::account_resolve(
        sender_id、
        量
        &env::current_account_id()、
        0,
        GAS_FOR_SINGLE_CALL*3、
    ));
}

ログ!(
    "current_leader: {} highest_bid: {}",
    self.current_leader、
    self.highest_bid
);

PromiseOrValue::Value(0)

}

#[private] pub fn account_resolve(&mut self, sender_id: AccountId, amount: u128) { 一致 env::p romise_result(0) { PromiseResult::NotReady => 到達不能!() PromiseResult::Successful(_) => { ext_ft_token::ft_transfer( self.current_leader.clone()、 self.highest_bid、 &FTTOKENや 0, GAS_FOR_SINGLE_CALL2、 ); self.current_leader = sender_id; self.highest_bid = 金額; } PromiseResult::失敗 => { ext_ft_token::ft_transfer( sender_id.clone()、 量 &FTTOKENや 0, GAS_FOR_SINGLE_CALL2、 ); ログ!("今すぐ戻る"); } }; }

前の入札者のアカウントが破棄された場合、新しい入札はブロックされます。

外部呼び出しの失敗を考慮すると、返せないトークンはその後の引き出しのためにステージングできます。

錆 pub fn withdraw_lost_funds(&mut self) { let account_id = env::p redecessor_account_id(); let amount = self.lost_funds.get(&account_id).expect("失われた資金はありません");

self.lost_funds.remove(&account_id);

ext_ft_token::ft_transfer(
    account_id、
    量
    &FTTOKENや
    0,
    GAS_FOR_SINGLE_CALL
);

}

!

3. オーナーのプライベートキーの喪失

特定の重要な関数は、契約の所有者のみが呼び出すことができます。所有者が秘密鍵を失った場合、これらの関数は実行できなくなります。

契約を管理するためにマルチシグネチャソリューションを採用し、シングルポイント障害を回避する必要があります。

錆 公開構造体MultiSigContract { 所有者:Vec、 required_confirmations:U32、 }

pub fn submit_transaction(&mut self, transaction: Transaction) { assert!(self.owners.contains(&env::p redecessor_account_ id())); // 確認待ちリストに取引を追加する }

pub fn confirm_transaction(&mut self, transaction_id: u64) { assert!(self.owners.contains(&env::p redecessor_account_ id())); // 確認数を増やす // 確認数が要求を満たす場合、取引を実行する }

上記の方法により、スマートコントラクトにおけるDoS攻撃のリスクを効果的に防ぐことができます。

! </accountid,></accountid,>

原文表示
このページには第三者のコンテンツが含まれている場合があり、情報提供のみを目的としております(表明・保証をするものではありません)。Gateによる見解の支持や、金融・専門的な助言とみなされるべきものではありません。詳細については免責事項をご覧ください。
  • 報酬
  • 7
  • 共有
コメント
0/400
ConsensusDissentervip
· 07-19 04:59
貴重な洞察はコレクションして学ぶ価値があります
原文表示返信0
MEVHunterZhangvip
· 07-18 23:52
さすが経験に基づく言葉です
原文表示返信0
PumpBeforeRugvip
· 07-18 15:28
ガス代は誰が支払うのかを理解する
原文表示返信0
GmGnSleepervip
· 07-17 00:43
安全第一に間違いはない
原文表示返信0
ImpermanentPhilosophervip
· 07-17 00:41
強制再起動すれば問題ありません。
原文表示返信0
GasFeePhobiavip
· 07-17 00:23
ガス代は大きな問題です
原文表示返信0
AllInAlicevip
· 07-17 00:21
ガスの最適化は非常に重要です
原文表示返信0
いつでもどこでも暗号資産取引
qrCode
スキャンしてGateアプリをダウンロード
コミュニティ
日本語
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)