# スマートコントラクトにおけるサービス拒否攻撃の詳細分析サービス拒否攻撃(DoS)は、スマートコントラクトが一時的または永続的に正常に使用できなくなる可能性があります。主な原因は次のとおりです:1. コントラクトのロジックに欠陥があります。例えば、いくつかの公開関数が計算の複雑さを考慮していないため、ガス上限を超えて取引が失敗する可能性があります。2. クロスコントラクト呼び出しにおいて、コントラクトの実行は外部コントラクトの状態に依存します。外部コントラクトの実行が信頼できない場合、本コントラクトの実行がブロックされる可能性があり、ユーザーの資金がロックされて出入金できなくなることがあります。3. 人為的要因、例えば契約所有者が秘密鍵を失うと、特定の特権関数が呼び出せなくなり、重要なシステム状態が更新できなくなる。以下に具体的な例を挙げてDoS攻撃の脆弱性を分析します:## 1. 外部から変更可能な大規模なデータ構造を走査以下はユーザーに「分配金」を提供するシンプルな契約です:さび#[near_bindgen]#[derive(BorshDeserialize、BorshSerialize)]pub struct コントラクト { パブ登録:Vec<accountid>、 パブアカウント: 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のサイズには制限がなく、悪意のあるユーザーによって操作される可能性があります。登録ユーザーが多すぎると、distribute_tokenの実行がGas制限を超えて取引が失敗する可能性があります。引き出しモードへの改造を提案します: すべてのユーザーに対して積極的に配当を行うのではなく、帳簿を付け、ユーザーが自分で報酬を引き出すことができるwithdraw関数を設定します。! [](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、 パブの払い戻し:ブール}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!("今すぐ戻る"); } };}このスマートコントラクトは、最高入札者のトークンを前回の入札者に返却する必要があります。前者が外部スマートコントラクトでアカウントをキャンセルした場合、システムは最高入札者を更新できなくなります。エラーハンドリング機構を追加することをお勧めします。例えば、返却できないトークンをスマートコントラクトのlost_foundアカウントに保存し、その後ユーザーが引き出せるようにします。## 3. 所有者の秘密鍵を紛失した部分合約関数はオーナーのみが実行できるように設定されており、重要なシステム変数を変更するために使用されます。オーナーが職務を果たせない(場合や、秘密鍵が紛失)された場合、資金がロックされるか、取引が一時停止される可能性があります。複数署名メカニズムを採用して単一のowner権限制御を代替し、分散型ガバナンスを実現することをお勧めします。以上を考慮すると、スマートコントラクトの開発においては、さまざまな潜在的なサービス拒否攻撃のリスクを十分に考慮し、適切な防止策を講じ、契約が長期的に安定して運用されることを確保する必要があります。! [](https://img-cdn.gateio.im/social/moments-7076cf1226a2276d1e4cd994d259841f)</u128></accountid,balance></accountid></accountid,></accountid>
三大スマートコントラクトDoS攻撃脆弱性の詳細と防止策
スマートコントラクトにおけるサービス拒否攻撃の詳細分析
サービス拒否攻撃(DoS)は、スマートコントラクトが一時的または永続的に正常に使用できなくなる可能性があります。主な原因は次のとおりです:
コントラクトのロジックに欠陥があります。例えば、いくつかの公開関数が計算の複雑さを考慮していないため、ガス上限を超えて取引が失敗する可能性があります。
クロスコントラクト呼び出しにおいて、コントラクトの実行は外部コントラクトの状態に依存します。外部コントラクトの実行が信頼できない場合、本コントラクトの実行がブロックされる可能性があり、ユーザーの資金がロックされて出入金できなくなることがあります。
人為的要因、例えば契約所有者が秘密鍵を失うと、特定の特権関数が呼び出せなくなり、重要なシステム状態が更新できなくなる。
以下に具体的な例を挙げてDoS攻撃の脆弱性を分析します:
1. 外部から変更可能な大規模なデータ構造を走査
以下はユーザーに「分配金」を提供するシンプルな契約です:
さび #[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");
}
この契約の状態データself.registeredのサイズには制限がなく、悪意のあるユーザーによって操作される可能性があります。登録ユーザーが多すぎると、distribute_tokenの実行がGas制限を超えて取引が失敗する可能性があります。
引き出しモードへの改造を提案します: すべてのユーザーに対して積極的に配当を行うのではなく、帳簿を付け、ユーザーが自分で報酬を引き出すことができるwithdraw関数を設定します。
!
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、 ); log!("今すぐ戻る"); } }; }
このスマートコントラクトは、最高入札者のトークンを前回の入札者に返却する必要があります。前者が外部スマートコントラクトでアカウントをキャンセルした場合、システムは最高入札者を更新できなくなります。
エラーハンドリング機構を追加することをお勧めします。例えば、返却できないトークンをスマートコントラクトのlost_foundアカウントに保存し、その後ユーザーが引き出せるようにします。
3. 所有者の秘密鍵を紛失した
部分合約関数はオーナーのみが実行できるように設定されており、重要なシステム変数を変更するために使用されます。オーナーが職務を果たせない(場合や、秘密鍵が紛失)された場合、資金がロックされるか、取引が一時停止される可能性があります。
複数署名メカニズムを採用して単一のowner権限制御を代替し、分散型ガバナンスを実現することをお勧めします。
以上を考慮すると、スマートコントラクトの開発においては、さまざまな潜在的なサービス拒否攻撃のリスクを十分に考慮し、適切な防止策を講じ、契約が長期的に安定して運用されることを確保する必要があります。
! </accountid,balance></accountid,>