🎉 #Gate Alpha 第三届积分狂欢节 & ES Launchpool# 聯合推廣任務上線!
本次活動總獎池:1,250 枚 ES
任務目標:推廣 Eclipse($ES)Launchpool 和 Alpha 第11期 $ES 專場
📄 詳情參考:
Launchpool 公告:https://www.gate.com/zh/announcements/article/46134
Alpha 第11期公告:https://www.gate.com/zh/announcements/article/46137
🧩【任務內容】
請圍繞 Launchpool 和 Alpha 第11期 活動進行內容創作,並曬出參與截圖。
📸【參與方式】
1️⃣ 帶上Tag #Gate Alpha 第三届积分狂欢节 & ES Launchpool# 發帖
2️⃣ 曬出以下任一截圖:
Launchpool 質押截圖(BTC / ETH / ES)
Alpha 交易頁面截圖(交易 ES)
3️⃣ 發布圖文內容,可參考以下方向(≥60字):
簡介 ES/Eclipse 項目亮點、代幣機制等基本信息
分享你對 ES 項目的觀點、前景判斷、挖礦體驗等
分析 Launchpool 挖礦 或 Alpha 積分玩法的策略和收益對比
🎁【獎勵說明】
評選內容質量最優的 10 位 Launchpool/Gate
Rust智能合約DoS攻擊漏洞分析及解決方案
Rust智能合約中的拒絕服務攻擊
拒絕服務(DoS)攻擊可能導致智能合約在一段時間內甚至永久無法正常使用。主要原因包括:
合約邏輯存在缺陷,如某些函數的計算復雜度過高,導致Gas消耗超出限制。
跨合約調用中,合約執行依賴外部合約狀態,可能被外部合約阻塞。
人爲因素,如合約所有者丟失私鑰,導致特權函數無法調用。
下面通過具體例子分析智能合約中的DoS攻擊漏洞。
1. 循環遍歷可被外部修改的大型數據結構
以下是一個用於給註冊用戶分紅的簡單合約:
rust #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec, pub accounts: UnorderedMap<accountid, balance="">, }
impl Contract { pub fn register_account(&mut self) { if self.accounts.insert(&env::predecessor_account_id(), &0).is_some() { env::panic("帳戶已註冊".to_string().as_bytes()); } else { self.registered.push(env::predecessor_account_id()); } log!("註冊帳戶 {}", env::predecessor_account_id()); }
}
該合約的問題在於registered數組大小沒有限制,可被惡意用戶操控變得過大,導致distribute_token函數Gas消耗過高。
推薦解決方案:
採用提現模式重構合約。讓用戶主動調用提現函數來獲取獎勵,合約只需記錄用戶可提現的獎勵數額。
2. 跨合約狀態依賴導致阻塞
考慮一個競價合約:
rust #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec, pub bid_price: UnorderedMap<accountid,balance>, pub current_leader: AccountId, pub highest_bid: u128, pub refund: bool }
impl Contract { pub fn bid(&mut self, sender_id: AccountId, amount: u128) -> PromiseOrValue { assert!(amount > self.highest_bid); if self.current_leader == DEFAULT_ACCOUNT { self.current_leader = sender_id; self.highest_bid = amount; } 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, amount, &env::current_account_id(), 0, GAS_FOR_SINGLE_CALL * 3, )); } log!( "當前最高出價者: {} 最高出價: {}", self.current_leader, self.highest_bid ); PromiseOrValue::Value(0) }
}
該合約的問題在於:必須成功退回前一位出價者的代幣,才能更新最高出價。如果前一位出價者注銷了帳戶,合約將無法完成退款而阻塞。
解決方法:
考慮外部合約調用可能失敗的情況,實現合理的錯誤處理。可以將無法退回的代幣暫存在合約中,後續允許用戶主動提取。
3. 合約所有者私鑰丟失
部分合約函數被設置爲只有所有者可執行,用於更改關鍵系統變量。如果所有者私鑰丟失,這些函數將無法調用,可能導致合約無法正常運行。
解決方法:
設置多個合約所有者共同治理,或採用多籤名機制來替代單一所有者的權限控制,實現去中心化治理。