「把它關掉」其實是四件不同的事

停止接單、停止簽章、改寫邏輯、停止動用你的資產,是四種不同的權力;同一方可能掌握其中幾項,應逐項查明控制者。

大部分討論會把它們混成一句「專案可以隨時停掉這個 Agent」。混在一起的後果是判斷失準:你以為撤銷授權就安全,卻沒發現合約邏輯還能被改;或者反過來,看到合約不可升級就放心,卻沒注意到真正決定行為的是一份鏈下設定檔。先把四件事分開,後面每一節才有明確的查證對象。

你想停下的東西實際按下按鈕的人生效速度你自己能做的事
對外接單的前端與 API營運團隊依營運端停用與佇列處理而定停止送出新任務;查明已接收任務是否取消
Agent 的簽章行為持有熱錢包金鑰或執行主機的人依金鑰、主機與備援停用情況而定自管時可停用自己的簽章服務;第三方代管時須另查撤權路徑
Agent 依循的合約邏輯升級權持有者(單一地址、多簽或 timelock)依升級流程、最短延遲與交易確認而定通常不能阻止別人升級;只有提領仍可用且時間足夠時才可能先退出
Agent 動用你資產的能力你持有的撤權能力,加上錢包與協議的限制依授權種類、數量與鏈上確認而定逐項撤銷 allowance、解除委派或移轉尚可控制的資產;不能追回已轉走的款項

第四列是你應先確認能否親自操作的一格,並非無條件有效。私鑰已外洩、資產已存入協議或提領遭暫停時,單純撤銷 allowance 不足以解決問題。若你已經把某個 Agent 接上自己的錢包,撤銷路徑與最大損失的算法在AI Agent 錢包權限:最大損失與控制設計裡有完整寫法,本頁不重複。

先為表格每列填上合約位址、多簽位址或團隊角色。無法辨認控制者的項目,暫記「未查到控制者」,留待後面的查證補足。

這份合約能不能被改?先把代理與升級權讀出來

從使用者實際互動的位址開始,沿著代理、實作與授權角色往下查。只抄到一個 owner 位址,還不足以確定誰能升級。

代理模式把狀態保留在代理位址,由另一份實作合約提供執行邏輯。ERC-1967 定義 implementation、beacon 與可選 admin 儲存位置,讓瀏覽器能辨識採用此標準的代理;它沒有替所有代理規定同一套升級權限。Read as Proxy 是讀取實作介面的入口,是否能升級仍要核對實際程式碼。

  1. 在區塊瀏覽器打開實際互動位址的 Contract 分頁。若提供 Read as Proxy,先記下代理與實作位址;沒有這個頁籤,不能直接推論它不可升級。下方是標準文件的公開頁截圖,頁面提供瀏覽器辨識代理的說明。
  2. 辨別代理種類。Transparent 模式要追查 ProxyAdmin 及其控制者;UUPS 要追查透過代理執行的升級函式與 _authorizeUpgrade 權限;Beacon 模式還要追到 beacon 的升級權。若權限由角色或另一份合約管理,繼續追到可執行的地址,不能只看 admin 是否為零。
  3. 查找 Upgraded、AdminChanged 或 BeaconUpgraded 等相關事件,對照原始碼中的升級路徑與事前公告。記下查證區塊、日期,以及查到的歷史交易雜湊;單純讀取欄位本身不會產生交易雜湊。
ERC-1967 公開標準頁,說明代理資訊的標準儲存位置
ERC-1967 標準文件公開頁,截圖於 2026 年 9 月。這是查證方法的文件示意,沒有對任何專案作出安全判定。

這裡有兩個常見誤讀。第一,看到「原始碼已驗證」不等於不可升級,驗證只證明公開的程式碼與鏈上位元組碼相符。第二,直接在實作位址讀到 owner 為零,不代表代理使用的儲存狀態也相同。UUPS 的 owner 或角色可能直接控制升級;必須按實際模式核對,不可一概說兩者無關。

查證筆記至少應能重走這條路:代理位址 → implementation 或 beacon → 升級函式 → 授權角色。附上查證區塊與日期,以及存在的升級交易;哪一段讀不到,就把結論停在那一段。

要幾把鑰匙才動得了它,鑰匙又在誰手上

門檻寫成幾之幾只是形式,關鍵是那些簽署人是不是各自獨立。

以假設的九名簽署人、五份簽署通過為例,門檻能限制單把金鑰,卻不能證明五份簽署由不同的人控制。地址同日建立或資金同源,只能作為進一步追查的線索,不能單憑這些就判定全部金鑰屬於同一人。我會把地址活動與身分揭露分開記錄,再查裝置、保管與組織是否獨立;沒有足夠材料時,就保留「獨立性未證實」的結論。

Timelock 的價值同樣要看實作細節。有效的 timelock 會把升級排進佇列,經過最短延遲後才可執行,這段延遲可能提供反應時間,但要扣掉發現事件、送出交易與等待確認的時間;提領若被暫停或有鎖定期,也不保證來得及退出。要查的是設定的最短延遲是多少、排程事件是否公開可訂閱,以及是否另外保留了不經延遲的緊急路徑。只要緊急路徑存在,公告上的延遲時間就不是最壞情況。

多簽紀錄保留 m/n 門檻、各地址的活動線索與身分證據;以 Safe 為例,還要核對已啟用的模組是否能採用另一套授權路徑執行交易。延遲紀錄另列最短秒數、可能繞過延遲的角色,以及你實際需要的退出步驟。兩份紀錄回答不同問題,不能只合成一個「分散程度」分數。

暫停開關保護的是誰

暫停多半是為了讓協議在事故中不再繼續失血,不保證同時保護你的提領權。

以 OpenZeppelin Pausable 為例,受 whenNotPaused 修飾的函式會在暫停時被擋下,whenPaused 則要求暫停後才能呼叫;光是繼承模組不會自動暫停所有函式。要查到提領與緊急退出的實際檢查:一般提領若被擋住,還需確認是否保留其他退出方式。這在事故當下可能是合理設計,但你必須事前知道,而不是在資金卡住時才發現。

放錢進去之前值得先問三個問題:暫停之後哪些函式仍可呼叫、誰有權暫停與解除、有沒有自動解除的時限。三題都要用合約與文件回答,不能只看團隊的口頭承諾。若專案沒有暫停機制,也不能直接加分;仍要查是否另有撤權、限額或停用特定功能的處置,不能把「沒有 pause」等同於完全沒有事故應變。

把一般提領、緊急退出、暫停及解除暫停的函式逐一列出,附上控制角色與原始碼位置。若查到歷史暫停事件,再補上開始與解除時間;沒有查到事件,不等於證明從未暫停。

鏈下的停機點:模型、RPC、主機與帳號

合約持續可用時,執行 Agent 的服務仍可能停機。查鏈下依賴時,我先問它會停止執行、排隊重試,還是切到另一套模型或節點。

Agent 可能依賴模型 API、外部 RPC、執行主機及作為指令入口的社群帳號,也可能自行託管或設有備援。某個服務失效是否影響執行,要看重試與切換機制。交易中斷、失敗或行為改變可能在鏈上留下結果;單靠交易紀錄,通常無法確定是哪些鏈下服務出了問題。

這一層的查證方式和鏈上不同。可用的材料是專案自己的架構說明、狀態頁、事故公告與歷史停機紀錄;沒有這些材料本身就是一個結論——這一層你無法評估。至於 Agent 的鏈上動作是否真的由模型決定,那是另一個問題,做法寫在如何驗證 AI Agent 的鏈上動作

這份依賴清單要附上可替換性、備援說明,以及能找到的公開中斷紀錄與日期。文件沒有說明的故障處置,就標成無法評估,別用鏈上正常交易替它作保。

控制權查證清單

下面四項供查完資料後逐一核對。它們不評分、不給投資建議,只要求你在下結論之前先把位址、延遲與日期寫下來。想把最大損失換算成具體金額,可以搭配權限與最大損失規劃器,計算全在你自己的瀏覽器完成。

檢查 01|讀出代理與升級權

查證動作
在區塊瀏覽器辨認代理種類,記錄 implementation 或 beacon,並追到實際的升級授權角色。
應取得的證據
代理位址、實作位址、admin 型別與升級歷史的交易雜湊
會推翻判定的訊號
以「原始碼已驗證」推論合約不可升級
本題判定規則
只對讀得到的欄位下結論,讀不到就標為未查到

檢查 02|量出真正的反應時間

查證動作
找出 timelock 的最短延遲,並確認是否存在不經延遲的緊急路徑。
應取得的證據
timelock 合約位址、最短延遲秒數、緊急角色是否存在
會推翻判定的訊號
直接採用公告文字裡寫的延遲天數
本題判定規則
以最短的那條路徑為準,不用最長的那條

檢查 03|實測你自己的撤銷路徑

查證動作
先用隔離的測試錢包與可承受損失的小額驗證相應撤銷步驟,記錄交易數、費用與確認結果;已懷疑受害時,不要為了測試再授權或存入資產。
應取得的證據
撤銷交易雜湊、耗時、失敗時的錯誤訊息
會推翻判定的訊號
假設介面上有按鈕就等於可撤銷
本題判定規則
未驗證的撤銷路徑標為未驗證;測試成功也只支持當時的設定與狀態

檢查 04|盤點鏈下停機點

查證動作
列出模型、RPC、主機與帳號依賴,並找出最近一次公開的中斷紀錄。
應取得的證據
依賴清單、是否有備援、事故公告連結與日期
會推翻判定的訊號
因為鏈上沒有異常就判定這一層健康
本題判定規則
缺乏材料時結論寫「無法評估」,不寫「沒有風險」

把查到的權限記下來

讀完每一列,應該能說清楚誰能改變什麼、最快何時生效,以及你的退出動作是否仍可執行。任何資金決策都還有合約漏洞、流動性與操作失誤造成損失的風險。

建議的欄位是:控制項目、持有者型別、門檻、生效延遲、對你的影響、證據連結、查證日期。每一列只放一件事;查不到的填「未查到」,不要留白——空白會在下次回顧時被誤讀成沒有風險。

會改變結論的條件也要一併寫下:升級權從多簽移到單一地址、timelock 延遲被調短、暫停範圍擴大到提領、簽署人名單變動。這些都是可以訂閱或定期重查的事件。治理承諾本身是否具備可執行性,另有一份檔案處理:產品收入是否為 Token Holder 帶來真實價值?

保留每次查證的日期與表格版本,下一次只要控制角色、延遲或退出條件變動,就更新受影響的列。這樣才看得出上一份結論為什麼失效。

常見問題

合約不可升級,是不是就代表沒有人能改它?

只代表那份合約的邏輯不能改。Agent 的行為還可能由可替換的設定合約、可更新的參數、鏈下的模型與提示詞決定,這些都不受合約不可變性保護。

Timelock 是不是愈長愈安全?

Timelock 會限制操作最早可執行的時間,無論你是否查看佇列。要利用這段時間退出,仍須透過監控或通知及時得知變更,並確認提領沒有被暫停或鎖定。若另有可繞過 timelock 的升級路徑,也要核對那條路徑的生效時間,不能只看公告中的延遲。

多簽人數多,是不是就等於分散?

不一定。先查門檻與其他執行路徑,再查金鑰是否由獨立的人保管;同日建址或同源資金只能提供線索。即使地址很多,若同一人能控制足夠份數的簽署,仍可單方面執行。

專案說權限已經放棄(renounce),要怎麼確認?

先辨認代理種類與升級授權函式,再核對放棄權限的交易和目前角色。owner 為零只能說明對應的所有權狀態;還要排除其他升級角色、ProxyAdmin 或 beacon 路徑。UUPS 尤其要查代理狀態中的授權邏輯,不能只讀實作位址的 owner。

本檔案使用的來源

  1. 升級智能合約|ethereum.org — 說明合約為何預設不可變,以及可升級模式改變了哪些信任假設。
  2. Proxy|OpenZeppelin Contracts 5.x — 對照 Transparent、UUPS 與 Beacon 的升級路徑,及 _authorizeUpgrade 的用途。
  3. Proxy Upgrade Pattern|OpenZeppelin Docs — 代理合約如何把儲存與邏輯分離,以及升級權放在哪個角色。
  4. ERC-1967: Proxy Storage Slots — 規範 implementation 與 admin 位址存放的固定 slot,是自行讀取升級權的依據。
  5. Proxy Contracts|Etherscan Information Center — 在區塊瀏覽器上辨識代理合約並讀取其實作位址的操作說明。
  6. Utils(含 Pausable)|OpenZeppelin Contracts 5.x — 暫停機制的標準實作,可用來對照專案的暫停範圍涵蓋哪些函式。
  7. Governance(含 TimelockController)|OpenZeppelin Contracts 5.x — Timelock 的角色劃分與最短延遲設定,可用來核對公告與生效的時間差。
  8. How do Safe Smart Accounts work?|Safe Docs — 多簽帳戶的門檻與簽署人管理方式,用於核對 m/n 設定的實際意義。
  9. What Are Token Approvals?|Revoke.cash — 說明 allowance 的運作與撤銷方式,對應你自己那一半的控制權。
  10. 節點即服務|ethereum.org — 外部 RPC 供應商是常見的鏈下單點依賴,這頁說明其角色與限制。