أمان العقود الذكية في Rust: الدفاع ضد هجوم حجب الخدمة
هجوم حجب الخدمة(DoS) سوف يؤدي إلى عدم إمكانية استخدام العقود الذكية بشكل طبيعي لفترة من الزمن، وقد يتسبب حتى في تعطيلها بشكل دائم. الأسباب الرئيسية تشمل:
تحتوي منطق العقد على عيب في التعقيد الحسابي العالي، مما يؤدي إلى استهلاك الغاز بما يتجاوز الحد.
الاعتماد على حالة تنفيذ العقد الخارجي عند استدعاء العقود عبر العقود الأخرى، قد يتم حظره بواسطة العقد الخارجي.
فقد مالك العقد المفتاح الخاص، ولا يمكنه تنفيذ الوظائف الرئيسية.
سوف نقوم بالتحليل هنا مع أمثلة محددة.
1. تجنب التنقل عبر هياكل البيانات الكبيرة التي يمكن التحكم فيها من الخارج
以下 هو عقد "تقسيم الأرباح" بسيط، ويواجه خطر هجوم حجب الخدمة:
صدأ
#[near_bindgen]
#[derive(BorshDeserialize ، BorshSerialize)]
عقد بنية pub {
الحانة المسجلة: Vec ،
حسابات pub: UnorderedMap<accountid, balance="">,
}
ل cur_account في self.registered.iter() {
Let balance = 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.
let transaction = &mut self.transactions[transaction_id as usize];
transaction.confirmations += 1 ؛
إذا كانت transaction.confirmations >= self.required_confirmations {
self.execute_transaction(transaction_id).
}
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
تسجيلات الإعجاب 7
أعجبني
7
6
مشاركة
تعليق
0/400
TokenomicsTherapist
· منذ 7 س
فقدان المفتاح الخاص حقيقي جداً هاها
شاهد النسخة الأصليةرد0
GasFeeNightmare
· 08-04 04:49
لا عجب أنه مستثمرين كبار في الغاز
شاهد النسخة الأصليةرد0
PretendingToReadDocs
· 08-04 04:49
لا يمكن تجنب هجمات DoS ، فما الذي يمكن مناقشته حول الأمان؟
أمان العقود الذكية Rust: 3 استراتيجيات رئيسية للدفاع ضد هجمات DoS
أمان العقود الذكية في Rust: الدفاع ضد هجوم حجب الخدمة
هجوم حجب الخدمة(DoS) سوف يؤدي إلى عدم إمكانية استخدام العقود الذكية بشكل طبيعي لفترة من الزمن، وقد يتسبب حتى في تعطيلها بشكل دائم. الأسباب الرئيسية تشمل:
تحتوي منطق العقد على عيب في التعقيد الحسابي العالي، مما يؤدي إلى استهلاك الغاز بما يتجاوز الحد.
الاعتماد على حالة تنفيذ العقد الخارجي عند استدعاء العقود عبر العقود الأخرى، قد يتم حظره بواسطة العقد الخارجي.
فقد مالك العقد المفتاح الخاص، ولا يمكنه تنفيذ الوظائف الرئيسية.
سوف نقوم بالتحليل هنا مع أمثلة محددة.
1. تجنب التنقل عبر هياكل البيانات الكبيرة التي يمكن التحكم فيها من الخارج
以下 هو عقد "تقسيم الأرباح" بسيط، ويواجه خطر هجوم حجب الخدمة:
صدأ #[near_bindgen] #[derive(BorshDeserialize ، BorshSerialize)] عقد بنية pub { الحانة المسجلة: Vec ، حسابات pub: 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(), DISTRIBUTOR, "ERR_NOT_ALLOWED");
}
تتمثل المشكلة في العقد في عدم وجود حد لحجم مصفوفة registered، مما يمكن المستخدمين الخبيثين من التلاعب بها وجعلها كبيرة جدًا، مما يؤدي إلى تجاوز استهلاك الغاز في وظيفة distribute_token.
الحل الموصى به هو اعتماد وضع "السحب":
صدأ pub fn distribute_token(& mut self, amount: u128) { assert_eq!(env::p redecessor_account_id(), DISTRIBUTOR, "ERR_NOT_ALLOWED");
}
pub fn withdraw(& mut self) { Let account = env::p redecessor_account_id(); let amount = self.accounts.get(&account).unwrap(); self.accounts.insert(&account, &0);
}
!
2. تجنب الاعتماد على الحالة في استدعاءات العقود المتعددة
下面是一个العقود الذكية示例:
صدأ #[near_bindgen] #[derive(BorshDeserialize ، BorshSerialize)] عقد بنية pub { الحانة المسجلة: Vec ، pub bid_price: UnorderedMap<accountid,balance>, pub current_leader: AccountId ، حانة highest_bid: u128 ، }
pub fn bid(&mut self, sender_id: AccountId, amount: u128) -> PromiseOrValue { أكد!(amount > self.highest_bid);
}
#[private] pub fn account_resolve(&mut self, sender_id: AccountId, amount: u128) { مطابقة ENV::p romise_result(0) { 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::Failed = > { ext_ft_token::ft_transfer( sender_id.clone(), المبلغ, و FTTOKEN ، 0, GAS_FOR_SINGLE_CALL * 2 ، ); log!("العودة الآن"); } PromiseResult::NotReady => غير قابل للوصول!(), }; }
المشكلة الموجودة في العقد هي أنه إذا قام أعلى مزايد سابق بإلغاء حسابه، فلن يتمكن المزايدون الجدد من تحديث الحالة بنجاح.
الحل هو تنفيذ معالجة الأخطاء بشكل معقول، مثل تخزين الرموز غير القابلة للاسترداد مؤقتًا، ثم يقوم المستخدم بسحبها لاحقًا.
صدأ عقد بنية pub { // ... pub lost_found: UnorderedMap<accountid, balance="">, }
pub fn account_resolve(&mut self, sender_id: AccountId, amount: u128) { مطابقة ENV::p romise_result(0) { PromiseResult::Successful(_) => { // منطق استرداد عادي } PromiseResult::Failed = > { // تخزين الرموز غير القابلة للاسترداد مؤقتًا دع lost_amount = self.lost_found.get(&self.current_leader).unwrap_or(0); self.lost_found.insert(&self.current_leader, &(lost_amount + self.highest_bid));
}
pub fn withdraw_lost_found(&mut self) { Let account = env::p redecessor_account_id(); المبلغ = self.lost_found.get(&account).unwrap_or(0); إذا كان المبلغ > 0 { self.lost_found.insert(&account, &0); ext_ft_token::ft_transfer(account, المبلغ, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL); } }
3. تجنب الأعطال الفردية
فقدان المفتاح الخاص لمالك العقد سيؤدي إلى عدم إمكانية استخدام الوظائف الحيوية الأساسية. الحل هو اعتماد آلية التوقيع المتعدد:
صدأ عقد بنية pub { مالكي الحانات: Vec\u003caccountid\u003e, حانة required_confirmations: U64 ، معاملات الحانة: Vec ، }
pub fn propose_transaction(&mut self, transaction: Transaction) { assert!(self.owners.contains(&env::p redecessor_account_id()), "ليس المالك "); self.transactions.push(transaction); }
pub fn confirm_transaction(& mut self, transaction_id: u64) { assert!(self.owners.contains(&env::p redecessor_account_id()), "ليس المالك ");
}
fn execute_transaction(& mut self, transaction_id: u64) { دع المعاملة = self.transactions.remove(transaction_id ك usize) ؛ // تنفيذ منطق المعاملات }
من خلال آلية التوقيع المتعدد، يمكن تجنب تعطل العقد الناتج عن فقدان مفتاح خاص لمالك واحد، مما يزيد من درجة لامركزية العقد وأمانه.
! </accountid,>< / accountid ، الرصيد > < / accountid ، >