iT邦幫忙

0

Day 20:合約升級與不可變性 — Proxy 模式的安全考量

  • 分享至 

  • xImage
  •  

在區塊鏈上,智能合約一旦部署後就不可修改。
這帶來兩種結果:
1. ✅ 安全性與信任提升(沒人能偷偷改合約)
2. ❌ 靈活性降低(發現錯誤或要新增功能時無法更新)

為了兼顧兩者,開發者常使用 Proxy(代理)模式 讓合約能「升級」。
但這同時也帶來新的安全風險。

💡 為什麼要升級合約?
• 修正漏洞
• 改變邏輯或新增功能
• 改 Token 規則或治理權限

如果不使用 Proxy,就只能「重新部署新合約」,導致:
• 原使用者資產需手動遷移
• 原合約狀態全部遺失

因此產生了「Proxy + Implementation」架構👇

⚙️ Proxy 模式基本架構
模組 功能說明
Proxy 合約 接收外部呼叫、儲存資料(storage)
Implementation(邏輯合約) 實際執行程式邏輯
Admin 管理者,可更改 implementation 地址(升級)

📖 核心機制:
Proxy 合約使用 delegatecall 呼叫邏輯合約,
執行邏輯時共用 Proxy 的 storage,讓狀態能延續。

🧠 delegatecall 的原理簡述
(bool success, ) = implementation.delegatecall(msg.data);

• delegatecall 讓被呼叫合約使用 呼叫者的 storage。
• 因此邏輯可以換掉,但資料仍保留。

⚠️ 危險點在於:
若 storage layout 改變(欄位順序不同),會導致資料錯亂!

🚨 常見安全風險
問題 說明 可能後果
🧱 Storage Layout 不一致/新版邏輯新增或重排變數/原本資料被覆寫,造成永久損壞
🔑 升級權限沒控好/任意帳號能更換 implementation/攻擊者替換成惡意合約,竊取資金
🧬 初始化錯誤(constructor 無效)/初始化邏輯錯誤或被重複呼叫/合約被惡意初始化,導致控制權被奪
🔁 delegatecall 錯誤使用/呼叫外部不安全邏輯/執行惡意 code,覆寫關鍵狀態

🧩 安全設計建議

✅ 使用 OpenZeppelin Transparent Proxy / UUPS 標準
✅ 在升級前:
• 比對 storage layout
• 測試升級流程(在測試鏈執行一次)
✅ 加入多簽、多層審批機制管理升級權限
✅ 加上事件紀錄(emit Upgraded(address newImplementation))方便追蹤
✅ 永遠記得:升級功能本身也是潛在攻擊面!

Proxy 模式是「安全 vs 靈活」的平衡。
沒設計好,就等於在安全的城牆上開了一道暗門。

— 開發者要確保:
✔️ 升級有規範
✔️ 權限有防護
✔️ 資料有一致性


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言