# Rustスマートコントラクト育成日記:サービス拒否攻撃防范サービス拒否(DoS)攻撃は、スマートコントラクトが一定期間、または永続的に正常に使用できなくなる可能性があります。一般的な原因には次のものが含まれます:1. コントラクトロジックにおける計算の複雑さの問題が、Gas消費が制限を超える原因となる。2. クロスコントラクト呼び出しの際、外部コントラクトの実行状態に対する不適切な依存が本コントラクトをブロックする原因となります。3. コントラクト所有者のプライベートキーが失われ、特権関数が呼び出せず、重要なシステム状態が更新できません。以下の具体的な例を通じて、DoS攻撃の脆弱性とその解決策を分析します。## 1. 外部から変更できる大規模なデータ構造をループ処理以下はシンプルな"分配"スマートコントラクトで、DoSリスクがあります:さび#[near_bindgen]#[derive(BorshDeserialize、BorshSerialize)]pub struct コントラクト { パブ登録:Vec<accountid>、 パブアカウント: UnorderedMap<accountid, balance="">,}impl コントラクト { 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 ); } }}問題は、registered配列のサイズに制限がなく、悪意のあるユーザーによって大きくなりすぎる可能性があるため、distribute_token関数の実行時にGas消費が制限を超えてしまうことです。提案された解決策:1. registered 配列のサイズを制限します。2. "出金"モードを採用し、ユーザーが自ら報酬を引き出すことを可能にし、契約が自動的に配布するのではなく。! [](https://img-cdn.gateio.im/social/moments-b7bbfcf4423b1cf19db56a3af95a7486)## 2. コントラクト間の状態依存によるコントラクトのブロック以下は"入札"スマートコントラクトの例です:さび#[near_bindgen]#[derive(BorshDeserialize、BorshSerialize)]pub struct コントラクト { パブ登録:Vec<accountid>、 pub bid_price: UnorderedMap<accountid,balance>, 公開current_leader: AccountId, パブhighest_bid:U128、 パブの払い戻し:ブール}impl コントラクト { pub fn bid(&mut self, sender_id: AccountId, amount: u128) -> PromiseOrValue<u128> { アサート!(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_CALL*2、 ); self.current_leader = sender_id; self.highest_bid = 金額; } PromiseResult::失敗 => { ext_ft_token::ft_transfer( sender_id.clone()、 量 &FTTOKENや 0, GAS_FOR_SINGLE_CALL*2、 ); log!("今すぐ戻る"); } }; }}問題は、契約の状態更新が外部契約の呼び出しに依存していることです。前の最高入札者のアカウントがキャンセルされている場合、後続の入札者は状態を更新できなくなります。提案された解決策:外部呼び出しが失敗する可能性を考慮し、合理的なエラーハンドリングメカニズムを実装します。例えば、返却できないトークンを契約内に一時保管し、後でユーザーが自主的に引き出すことを許可します。## 3. 所有者のプライベートキーの喪失多くの契約には所有者のみが実行できる特権関数があります。所有者の秘密鍵が失われると、これらの関数は呼び出せなくなり、契約が正常に機能しなくなる可能性があります。提案された解決策:1.複数の契約所有者を設定して、共同で管理します。2. 単一の所有者の制御に代わってマルチシグネチャメカニズムを採用する。3. 非中央集権的なスマートコントラクトガバナンスメカニズムを実現する。これらの対策を通じて、スマートコントラクトにおけるサービス拒否攻撃のリスクを効果的に低減し、契約の安全性と信頼性を向上させることができます。! [](https://img-cdn.gateio.im/social/moments-7076cf1226a2276d1e4cd994d259841f)</u128></accountid,balance></accountid></accountid,></accountid>
RustスマートコントラクトDoS攻撃防范実戦ガイド
Rustスマートコントラクト育成日記:サービス拒否攻撃防范
サービス拒否(DoS)攻撃は、スマートコントラクトが一定期間、または永続的に正常に使用できなくなる可能性があります。一般的な原因には次のものが含まれます:
コントラクトロジックにおける計算の複雑さの問題が、Gas消費が制限を超える原因となる。
クロスコントラクト呼び出しの際、外部コントラクトの実行状態に対する不適切な依存が本コントラクトをブロックする原因となります。
コントラクト所有者のプライベートキーが失われ、特権関数が呼び出せず、重要なシステム状態が更新できません。
以下の具体的な例を通じて、DoS攻撃の脆弱性とその解決策を分析します。
1. 外部から変更できる大規模なデータ構造をループ処理
以下はシンプルな"分配"スマートコントラクトで、DoSリスクがあります:
さび #[near_bindgen] #[derive(BorshDeserialize、BorshSerialize)] pub struct コントラクト { パブ登録:Vec、 パブアカウント: UnorderedMap<accountid, balance="">, }
impl コントラクト { 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()); }
}
問題は、registered配列のサイズに制限がなく、悪意のあるユーザーによって大きくなりすぎる可能性があるため、distribute_token関数の実行時にGas消費が制限を超えてしまうことです。
提案された解決策:
registered 配列のサイズを制限します。
"出金"モードを採用し、ユーザーが自ら報酬を引き出すことを可能にし、契約が自動的に配布するのではなく。
!
2. コントラクト間の状態依存によるコントラクトのブロック
以下は"入札"スマートコントラクトの例です:
さび #[near_bindgen] #[derive(BorshDeserialize、BorshSerialize)] pub struct コントラクト { パブ登録:Vec、 pub bid_price: UnorderedMap<accountid,balance>, 公開current_leader: AccountId, パブhighest_bid:U128、 パブの払い戻し:ブール }
impl コントラクト { pub fn bid(&mut self, sender_id: AccountId, amount: u128) -> PromiseOrValue { アサート!(amount > self.highest_bid);
}
問題は、契約の状態更新が外部契約の呼び出しに依存していることです。前の最高入札者のアカウントがキャンセルされている場合、後続の入札者は状態を更新できなくなります。
提案された解決策:
外部呼び出しが失敗する可能性を考慮し、合理的なエラーハンドリングメカニズムを実装します。例えば、返却できないトークンを契約内に一時保管し、後でユーザーが自主的に引き出すことを許可します。
3. 所有者のプライベートキーの喪失
多くの契約には所有者のみが実行できる特権関数があります。所有者の秘密鍵が失われると、これらの関数は呼び出せなくなり、契約が正常に機能しなくなる可能性があります。
提案された解決策:
1.複数の契約所有者を設定して、共同で管理します。
単一の所有者の制御に代わってマルチシグネチャメカニズムを採用する。
非中央集権的なスマートコントラクトガバナンスメカニズムを実現する。
これらの対策を通じて、スマートコントラクトにおけるサービス拒否攻撃のリスクを効果的に低減し、契約の安全性と信頼性を向上させることができます。
! </accountid,balance></accountid,>