開圖三天之後,你的代幣還顯示著佔位圖。你持有的一個系列,突然顯示出與上週不同的屬性。這兩件事都不是關於代幣本身的:它們說的都是合約裡的一個字串,以及這個字串另一端的東西。凍結與刷新,就是描述這個字串能變成什麼、又不能變成什麼的兩個詞。
代幣記著什麼,又沒記什麼
一個 NFT 是一個智能合約記在某個持有者地址名下的編號。名稱、描述和圖像都不在這條記錄裡。
ERC-721 這個代幣標準把它們放在一個函數後面。給定一個代幣編號,tokenURI 會回傳一個統一資源標識符;規範還補了一句,這個 URI 可以指向一份符合 ERC721 Metadata JSON Schema 的 JSON 檔案。
這份 schema 只有三個屬性:name 標識這個 NFT 所代表的資產,description 描述它,image 是一個指向某個圖像 MIME 類型資源的 URI。所以圖像是第二跳:合約指向一份文件,文件再指向一個檔案。
除了編號和持有者,應用展示給你的東西都是從那份文件裡讀來的,不是從鏈上讀來的。所有人都在看的那一部分,恰恰是鏈沒有保存的那一部分。
指針指向哪裡,決定了什麼能變
代幣 URI 是一個字串,而這個字串可以是好幾種不同的東西。它可以是某個人營運的伺服器上的一個網址。它可以是一個圍繞內容標識符構造的 IPFS 地址。它也可以把整份文件內聯地帶在自己身上,於是根本不需要去取任何東西。
這個區別之所以重要,在於它們各自可能變成什麼。網址命名的是位置,不是內容:營運那台伺服器的人明天可以在同一個網址上回傳不同的位元組,而鏈上不會因此發生任何變化。內容標識符則不同。IPFS 文件寫著,CID 基於內容的加密雜湊,而內容上的任何差異都會產生一個不同的 CID。所以 CID 無法解析到被改過的內容,因為被改過的內容就是另一個 CID,需要另一個指針。
內聯文件又往前走了一步,因為已經沒有可以被攔截的取回動作了。它的代價是體積,因為它的每一個位元組都佔著合約儲存。
| 代幣 URI 指向哪裡 | 另一端以後能不能給出不同的內容 | 圖像要變,必須先變什麼 |
|---|---|---|
| 別人伺服器上的一個網址 | 能 | 鏈上什麼都不用變 |
| 一個 IPFS 內容標識符 | 不能 | 合約必須回傳另一個 URI |
| 編碼在 URI 自身裡的文件 | 不能 | 合約必須回傳另一個 URI |
元數據凍結到底是什麼意思
凍結是一個關於兩把鎖的說法,只有兩把鎖都合上時它才成立。第一把鎖在另一端:指針背後的內容不能被換成別的內容。第二把鎖在指針本身:合約不能被弄得交回另一個 URI。
一個系列可以把每一個檔案都放到 IPFS 上、公布內容標識符,同時仍然留著一個允許部署者設定新 base URI 的函數。內容尋址合上的是第一把鎖,第二把鎖還開著。一個 10,000 枚代幣的系列可以由單一的 base URI 提供服務,這時候一筆所有者交易就會改掉其中每一個編號所解析到的東西。
所以凍結要這麼讀,就像你讀任何一個合約上的所有者特權一樣。問題不是合約今天做了什麼,而是持有所有者密鑰的人還能讓它做什麼。
你看到的為什麼是一份快取副本
市場與錢包不會在你每一次捲動時都去呼叫 tokenURI 並取一份文件。它們只讀一次,自己留一份 JSON 副本,把圖像下載下來,然後把這份副本發給你;因為渲染一個圖庫若換別的做法,就意味著每一格都要向站點無法控制的伺服器發出一次外部請求。
於是這個答案有了三份副本,而它們可能彼此不一致:合約現在回傳什麼、那個 URI 上的文件現在寫著什麼、以及索引器上一次看的時候記下了什麼。顯示錯了,說的是第三份副本,而不是前兩份錯了的證據。
ERC-4906 的存在正是因為這道縫。它的標題是 EIP-721 Metadata Update Extension,它加了一個 MetadataUpdate 事件;用它自己的話說,是為了讓 NFT 市場這類第三方平台能夠及時更新 NFT 的圖像與相關屬性。另有一個 BatchMetadataUpdate 事件,一次覆蓋一段編號區間。它給出的動機是:合約本來就已經各自為此發出自己的事件,而為每一個系列各建一套單獨的方案,對讀取這些事件的平台來說是額外的工夫。
刷新到底做了什麼
刷新是給索引器的指令,不是給鏈的。它告訴平台把記下的東西扔掉、把整套讀取再做一遍:呼叫 tokenURI,取回回傳的東西,解析它,再把 image 欄位裡指名的那個檔案重新下載一次。沒有任何東西被簽名,沒有手續費,合約也沒有被動過。
所以刷新只在一種情形下有用:存下來的那份副本落後於當前的答案。如果合約現在回傳一個新的 URI,或者舊 URI 上的文件現在是另外一批位元組,刷新就會把顯示拉回一致。如果這兩件事都不成立,它只是用一份一模一樣的副本替換掉存著的那一份。
刷新是 ERC-4906 所自動化的那件事的手動版本:當一個系列發出更新事件時,盯著它的索引器不用別人來要求就會重做這次讀取。
什麼時候刷新解決不了問題
有用的問題不是要不要刷新,而是你面對的是哪一種故障,因為互不相干的故障都以同一種樣子出現:圖不對,或者圖沒了。
| 你看到的 | 底下真正發生的 | 刷新能不能改變它 |
|---|---|---|
| 開圖之後仍是佔位圖 | 合約仍然回傳開圖前的 URI | 在合約回傳新的那個之前不能 |
| 圖裂了,文件還能打開 | image 的 URI 已死或無法到達 | 不能,要修的地方在託管方 |
| 什麼都載入不出來 | 元數據文件無法到達 | 不能 |
| 屬性與文件對不上 | 存著的副本過時了 | 能 |
| 圖對,但系列頁不對 | 你看的是另一個合約 | 不能 |
指針已死的那幾行,正是被讀成平台故障的那幾行。如果代幣 URI 是一個網址,它背後的伺服器可以被關掉,而指針會繼續指著空處。如果它是一個內容標識符,同樣的結果換一條路到達:IPFS 文件寫著,IPFS 保證網絡上的任何內容都是可被發現的,但它不保證任何內容是持久可得的;也寫著,數據可以被固定到一個或多個 IPFS 節點上,以免在垃圾回收時被刪除。沒有任何節點持有的 CID,是一個有效而且永久的、指向不存在之物的名字。
要求刷新之前該查什麼
三次讀取就能把這些情形分開,而且沒有一次需要市場是好的。
先讀合約。在區塊瀏覽器上打開這個系列的合約,用你的代幣編號呼叫 tokenURI。回傳的那個字串就是鏈上的答案,也是三份副本裡唯一被鏈背書的一份。
然後打開它回傳的東西。取回那個 URI 並讀那份 JSON。如果 name、description 與 image 裡裝著你預期的內容,那麼鏈這一側是對的,問題在它的下游。如果這個 URI 打不開,任何刷新都變不出一份並不存在的文件。
再順著 image 欄位走一遍,因為一份文件可以完好無損,而它所指名的那個檔案已經不在了,託管它的主機與提供元數據的那台也不是同一台。當這三次讀取都正確、而市場仍然顯示著別的東西時,那才是刷新的場合,而且是唯一的場合。
小結
元數據是鏈所指向的一份文件,不是鏈所保存的一樣東西。凍結意味著兩把鎖都合上了:另一端不能給出不同的內容,合約也不能被弄得指向別處。只有一把鎖不叫凍結,而內容尋址本身只合上第一把。
刷新碰不到這些。它重新讀一遍指針與文件,並覆蓋掉一份快取副本,所以它只修一種故障:顯示落後了。讀 tokenURI,打開它回傳的東西,再順著 image 欄位走。這三次讀取把需要再看一次的索引器,和末端已經什麼都沒有的指針區分開來。想繼續打好這些基礎,請追蹤 Bitbase(幣貝)學院的更多內容。
相關閱讀
幣貝上與本主題相關的其他文章:
風險披露:本文為 Bitbase(幣貝)學院的科普內容,僅供教育與資訊參考,不構成任何投資、交易、稅務或財務建議。加密資產波動劇烈,請自行評估風險。本文撰寫於 2026 年 9 月,請以官方最新資訊為準。
參考資料
[1] Ethereum Improvement Proposals,ERC-721: Non-Fungible Token Standard eips.ethereum.org
[2] Ethereum Improvement Proposals,ERC-4906: EIP-721 Metadata Update Extension eips.ethereum.org
[3] IPFS 文檔,Content Identifiers (CIDs) docs.ipfs.tech
[4] IPFS 文檔,Persistence, permanence, and pinning docs.ipfs.tech






