﻿---
title: "可升級智慧合約"
description: "可升級智慧合約在授權主體替換或重新導向實作時，保留代理地址和狀態。這種彈性也帶來儲存、初始化、治理與監控風險。"
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 可升級智慧合約

> 僅供教育參考，不構成投資或安全建議。可升級性可能賦予特權主體改變合約行為的權力，並可能造成損失。

<a id="answer"></a>

## 直接答案

可升級智慧合約是指這樣一種已部署系統：它不必讓使用者遷往新的主要地址，也不必放棄該地址保存的狀態，就能改變實際執行的邏輯。在相容以太坊的網路上，常見設計是由代理保存狀態，並透過 `delegatecall` 將呼叫轉送給實作合約。獲授權的升級會更換代理使用的實作，而代理地址、儲存和餘額維持不變。

這並不是改寫不可變的位元組碼，而是在應用程式前增加一層間接尋址。升級機制可以修正缺陷、增加功能，但也建立了一條能改變提款、費用、權限或記帳方式的特權控制路徑。因此，使用者既要評估目前程式碼，也要評估未來程式碼由誰、依何種規則決定。

並非所有代理都可升級，也並非所有可變系統都使用代理。有些專案部署新合約並遷移狀態，另一些則永久關閉升級能力。實際鏈上架構和權限比前端標籤更重要。

<a id="mechanism"></a>

## 運作方式

呼叫者向代理地址傳送交易後，代理讀取實作地址，並透過 `delegatecall` 在代理的儲存環境中執行實作程式碼。程式碼來自實作合約，但讀寫作用於代理儲存，原始呼叫者和附帶價值也會保留。ERC-1967 統一了實作、Beacon 和管理員儲存槽，方便工具識別常見代理部署。

透明代理把升級管理放在代理中，並區分管理員呼叫與使用者呼叫。UUPS 代理把升級邏輯放在實作中，並使用基於 ERC-1822 的相容介面，因此實作內的升級授權特別重要。Beacon 代理從 Beacon 取得實作，一次 Beacon 更新就可能改變多個代理。不同模式具有不同的信任邊界和失效方式。

狀態相容性是核心工程限制。新實作必須正確解讀既有儲存；調整變數順序、刪除變數或變更型別都可能破壞狀態，繼承關係改變也可能造成相同後果。僅追加配置、預留儲存間隙或 ERC-7201 命名空間儲存有助於管理演進，但仍須逐版本驗證。

建構函式初始化的是實作本身，而不是代理儲存。因此代理部署通常要為相應版本呼叫一次 `initialize` 等初始化器。實作應鎖定直接初始化，後續遷移則應使用範圍明確的再初始化器。公開或可重複呼叫的初始化器可能讓攻擊者奪取角色或覆寫設定。

穩健的升級流程包括：

1. 固定舊實作和擬議實作的原始碼、編譯設定、相依項、儲存配置、部署地址與預期位元組碼。
2. 審查程式碼差異、儲存相容性、初始化或遷移、授權、外部相依與回復假設，並在分叉環境中測試完整升級交易。
3. 公布提案與實作地址，嚴格執行公開聲明的多簽、治理和時間鎖流程，不保留未揭露的繞過路徑。
4. 執行後核驗實作槽或 Beacon 槽、事件、位元組碼、初始化狀態、角色與關鍵不變量，並記錄區塊。
5. 持續監控儲存槽、角色和參數變化，制定不假定回復必然安全的事件應變方案。

<a id="example"></a>

## 範例

假設某借貸協定需要新增還款功能，其代理目前委派給實作 A。團隊部署實作 B，確認 B 只在儲存末尾追加變數，並準備遷移呼叫。治理方公布位元組碼，並將升級置於 48 小時時間鎖之後。執行完成後，同一代理地址改為委派給 B，既有餘額仍保存在代理儲存中。

這套流程的可靠程度取決於控制措施。使用者應確認實作槽確實由 A 變為 B、遷移只執行一次，且角色和餘額符合預期。如果守護者可以繞過時間鎖，或簽署者能把 B 換成任意程式碼，那麼即使常規提案依公開流程執行，這些權力仍屬於實際信任模型。

<a id="risks"></a>

## 風險

- **特權替換：**管理員、多簽、治理合約或遭竊金鑰可以安裝惡意或有缺陷的邏輯。
- **儲存損壞：**不相容的配置可能錯誤解讀餘額、所有者、映射或帳務資料。
- **初始化失敗：**遺漏、重複或暴露的初始化器可能使系統無法使用或轉移控制權。
- **模式特有故障：**透明、UUPS、Beacon 和自訂代理的失效方式不同；模式名稱不能證明實作正確。
- **治理表演：**公開聲稱的時間鎖或投票可能存在緊急繞過、延遲過短、投票權集中或簽署安全薄弱等問題。
- **不安全的遷移或回復：**新版本可能不可逆地改變狀態，恢復舊程式碼未必能恢復舊含義。
- **驗證缺口：**實作原始碼經過驗證，並不能單獨證明代理指向它、使用預期管理員或具有預期初始化狀態。
- **監控與整合風險：**區塊瀏覽器、介面、稽核方和整合方可能仍追蹤舊實作，或遺漏影響全部 Beacon 代理的更新。

<a id="misconceptions"></a>

## 常見誤解

- **「這個地址上的合約不可變。」**代理位元組碼可能不可變，但實際行為可透過實作槽或 Beacon 槽改變。
- **「多簽使升級去中心化。」**只有簽署者彼此獨立、門檻、營運和更換規則都可靠時，它才真正減少對單一金鑰的依賴。
- **「時間鎖能阻止惡意升級。」**它只提供觀察和退出時間，不能讓擬議程式碼自動變得安全，也無法幫助不能退出的使用者。
- **「儲存檢查通過就證明升級安全。」**它只處理配置相容性，不涵蓋商業邏輯、授權、預言機、遷移或經濟錯誤。
- **「放棄升級權一定會消除控制。」**必須在鏈上檢查管理員、Beacon、治理合約、UUPS 授權和替代路徑；表面上的放棄可能仍留下其他通道。

<a id="related"></a>

## 相關主題

- [智慧合約](/zh-tw/crypto/smart-contract/)
- [如何閱讀智慧合約稽核](/zh-tw/crypto/contract-audit/)
- [多重簽名錢包](/zh-tw/crypto/multisig-wallet/)
- [時間鎖](/zh-tw/crypto/timelock/)

<a id="sources"></a>

## 來源

- [ERC-1967: Proxy Storage Slots](https://eips.ethereum.org/EIPS/eip-1967) - Ethereum Improvement Proposals（查閱日期：2026-08-22）
- [ERC-1822: Universal Upgradeable Proxy Standard (UUPS)](https://eips.ethereum.org/EIPS/eip-1822) - Ethereum Improvement Proposals（查閱日期：2026-08-22）
- [ERC-7201: Namespaced Storage Layout](https://eips.ethereum.org/EIPS/eip-7201) - Ethereum Improvement Proposals（查閱日期：2026-08-22）
- [Proxy Upgrade Pattern](https://docs.openzeppelin.com/upgrades-plugins/proxies) - OpenZeppelin Docs（查閱日期：2026-08-22）
- [Writing Upgradeable Contracts](https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable) - OpenZeppelin Docs（查閱日期：2026-08-22）
- [Proxy](https://docs.openzeppelin.com/contracts/5.x/api/proxy) - OpenZeppelin Docs（查閱日期：2026-08-22）
- [Layout of State Variables in Storage and Transient Storage](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html) - Solidity Documentation（查閱日期：2026-08-22）

Source: https://wiki.fcontext.com/zh-tw/crypto/upgradeable-contract/index.mdx
