Meme Atlas AZ · burn-events-supply-evidence

銷毀地址不等於供應扣減:把一次「已銷毀」說法還原成四欄證據

把一句「已銷毀」拆成事件、控制、時間與供應欄位四欄:哪些字樣才算供應扣減,每一欄實際怎麼填。

發布
更新
編輯責任
Meme Atlas AZ

一句「已銷毀」讀起來像單一事實,實際上同時押了三件事:某筆交易確實發生過、發起它的人具備發起它的資格、代幣的某一個供應欄位因此變小了。三件同時成立,這句話才站得住。只有第一件成立的時候,它描述的可能只是一次普通轉帳被寫成了銷毀。

同一筆轉出可能只是換了持有人,也可能真的離開了供應統計。兩者在觀察頁面上看起來相近,寫進研究紀錄卻是不同的兩行字,而區分它們靠的不是「已銷毀」這三個字,是底下那幾樣可以逐項對照的東西。

底下按這個分岔往下走:先看標準對銷毀說了什麼、沒說什麼,再逐欄寫事件證據、控制證據、時間與受影響的供應欄位要留下什麼。這裡說的四欄指供應事件這一組,與本站權限那一篇用的四欄不是同一套,欄名不能互換。全文不涉及任何具體代幣,不對誰給出安全與否的判斷,也不談價格與買賣。

EIP-20 只替「創造」定了慣例,銷毀那一側是空的

先確認一件經常被跳過的事:銷毀不是 ERC-20 標準裡的動作。

EIP-20 列出的方法只有 name、symbol、decimals、totalSupply、balanceOf、transfer、transferFrom、approve、allowance,事件只有 Transfer 與 Approval。沒有銷毀函式,也沒有一個叫 Burn 的事件。標準對 totalSupply 的全部描述只有一句 "Returns the total token supply.",至於這個數字怎麼變動、什麼情況下該變小,規範沒有規定。

標準確實定了一條跟供應變動有關的慣例,方向卻在相反的那一端:創造新代幣的合約 "SHOULD trigger a Transfer event with the _from address set to 0x0 when tokens are created"。零地址出現在 from 這一側,用來標記這批代幣是新出現的。輪到銷毀,標準沒有給出任何 to 側的慣例。

ethereum.org 的 ERC-20 說明頁(該頁自標最後更新為 2026 年 7 月 9 日)通篇沒有出現 burn 這個詞,跟上面這條對得上。

所以「它是標準 ERC-20,所以銷毀會反映在總量上」這種推論從一開始就沒有落腳點。一次銷毀能不能扣減供應,要看合約自己怎麼寫,以及那筆交易實際走了哪條路。

事件證據:to 是零地址,而且總量真的下降

實務上被廣泛採用的寫法來自 OpenZeppelin。它的 5.x 版 ERC20 文件對內部函式 _burn(account, value) 的描述是:從 account 銷毀一定數量的代幣,降低總供應,並 "Emits a IERC20.Transfer event with to set to the zero address"。

這段文字給出的是一組簽名,兩個部分要同時出現:Transfer 事件的 to 欄位為零地址,以及總供應隨之下降。研究紀錄裡值得原樣抄下的是這兩項,而不是某個頁面上的「已銷毀」四個字。

兩項缺一,能支持的說法就跟着變窄。只記事件不記總量差,你證明的是曾經發生過一筆 to 為零地址的事件;只記總量差不記事件,你證明的是兩個時點的總量不一樣,中間夾着什麼交易並不清楚。把兩項並排寫進紀錄,比寫一句結論省事,也更禁得起別人回頭查。

抄事件的時候有個小習慣值得養成:value 按鏈上原始單位抄,decimals 單獨記一欄,換算過的人類可讀數字另起一行寫。三者混在一格裡,過幾週再看就分不清當初抄的是哪一個。

由條文推出的一個看法:送進「黑洞地址」為什麼多半不會動到 totalSupply

同一份文件在公開的 transfer 函式底下寫了一條 Requirements:"to cannot be the zero address";transferFrom 那一條是 "from and to cannot be the zero address",錯誤型別裡列有 ERC20InvalidReceiver。

把這條跟上一節那條放在一起,會得到一個直接的結論:普通轉帳這條路根本送不進零地址。因此任何一個被公開稱作銷毀地址、又能正常收到代幣的地址,必然是個非零地址;代幣轉過去之後只是換了持有人,餘額仍然計在 totalSupply 裡面。這一層是本文由前述兩條條文自行推出的看法,不是 OpenZeppelin 的表述,也不是任何平台的官方說法,引用的時候要照這個強度寫。

至於具體哪些地址被叫作黑洞地址,本版未核——沒有取得官方定義,紀錄裡就寫「被公開稱為銷毀的非零地址」,把地址原樣抄下來,不替它加上已銷毀的標籤。這類地址若被算進持有者名單,讀出來的分布也會跟着變形,那是另一個題目,本文只往上游問一句:它憑什麼叫銷毀地址。

事件筆數會說謊的兩種情況:零值轉帳與 flash mint

EIP-20 裡有一條註記:"Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event"。數量為零的轉帳照樣要發事件。所以「這個代幣有很多筆銷毀事件」這種說法,在沒有逐筆看過 value 之前,換算不出任何供應變化。

另一種情況來自 ERC20FlashMint。OpenZeppelin 對它的描述是提供 "token level support for flash loans through the minting and burning of ephemeral tokens",並註明標準化為 ERC-3156。鑄與毀成對發生在同一筆交易之內,臨時代幣出現又消失。只數筆數的人會看到銷毀事件變多,總供應在交易結束後卻回到原處。

這兩種情況指向同一個習慣:數之前先想清楚你要的是筆數還是數量,兩者不能互推。

控制證據:銷毀函式來自擴充,burnFrom 走的是 allowance

第二欄問的是誰能發起這個動作,以及這一筆是憑什麼發起的。

burn 與 burnFrom 並不在核心 ERC20 裡面,它們來自擴充 extensions/ERC20Burnable.sol。同一份文件還說明核心 ERC20 "is agnostic to the way tokens are created",鑄造與銷毀兩側的安排都交給實作決定。一份合約有沒有公開的銷毀入口,要到它自己的程式碼裡確認,從「它是 ERC-20」推不出來。

burnFrom(account, value) 的語義是從呼叫者的 allowance 扣減,文件寫明呼叫者必須對 account 的代幣持有至少 value 的授權額度。這一條在紀錄裡的作用是把兩個地址分開:交易由誰簽出,代幣從誰的餘額裡消失,可以不是同一個人。只寫「某某地址銷毀了代幣」,這一層就丟了。

誰持有那些權限、事後還能不能再鑄,屬於權限那一面的讀法,本站已在合約權限狀態怎麼讀寫過,這裡不重複,只提醒一句:控制欄要記的是這一筆的簽名依據,權限現狀屬於另一欄。

銷毀不會把上限拉低:ERC20Capped 的 cap 建構後不可變

有一種說法把銷毀跟供應上限綁在一起,像是燒掉多少、天花板就往下降多少。文件不支持這個。

ERC20Capped 的 cap "is immutable, it can only be set once during construction",超過時拋出 ERC20ExceededCap(increasedSupply, cap)。這個機制約束的是供應往上增加的那一側,文件沒有提到銷毀會降低 cap。

紀錄裡因此要把兩格分開:這次事件之後 totalSupply 是多少,cap 有沒有變動。多數時候第二格的答案是沒有變,但把它寫上去,才說明你確認過,而不是預設它不會變。

Solana 的 Burn、BurnChecked 與凍結權限

換到 Solana,同一件事換了一整套詞。

官方文件寫的是,銷毀 "permanently decreases a token account balance and reduces the mint's total supply by the same amount",執行者是 Token Program 的 Burn 或 BurnChecked 指令。帳戶餘額與 mint 的總供應同時下降,這一點比 EVM 那邊直白。

BurnChecked 多要一個參數:呼叫者要提供 mint 的 decimals,指令據此 "verify the expected token precision before burning"。看到交易走的是 BurnChecked,紀錄裡能多支持一件事,就是精度在鏈上被核對過。

簽名這一側,文件寫的是 token account 的 owner 或獲授權的 delegate 簽署交易;在 Token Extension Program 之下,mint 的 permanent delegate 也能授權銷毀。permanent delegate 的完整語義本版只取得這一句,其餘未核,紀錄就照這一句的強度寫,不往外延伸。

還有兩條限制值得單獨留一行。原生 mint 不支援銷毀,文件要求改用 CloseAccount;至於 CloseAccount 對供應欄位到底做了什麼,本版未核,不往下推。另一條是 freeze authority,它的定義是被授權凍結某個 Token Account 內代幣、使其無法轉移或銷毀的帳戶——同一個權限同時擋住轉帳和銷毀這兩件事,讀的時候容易只記住前半句。

Mint 狀態裡還有 mint_authority、supply、decimals、is_initialized、freeze_authority 幾個欄位。文件說得很清楚:沒有 mint authority,這個 mint 才是固定供應、不能再鑄。反過來說,它還在的時候,這次扣掉的量後續會不會被補回來,銷毀這一欄回答不了。

四欄記錄:一次「已銷毀」說法要留下什麼

四欄的欄名沿用本站供應量、市值與 FDV提過的那一組,那裡只列了欄名,底下寫的是每一欄實際怎麼填。

順序是事件、控制、時間、受影響的供應欄位。控制欄排在時間欄前面,因為時間欄最好填,先填它的人常常把兩個高度之間的總量差直接算到那一筆交易頭上;讀慢一點換到的好處只有一個,就是不會把一份每格都填滿的紀錄掛到錯的交易上。

填的時候有兩條硬規定。第一條:事件的 to 讀出來是非零地址,就寫「移轉至該地址」,不寫「銷毀」,措辭不隨頁面上的說法走。第二條:欄位取不到寫「未取得」,不填零——供應差是拿這些格子做減法算出來的,零是一個真實的減項,未取得是一個空格,兩者混用會讓算出來的差額憑空多一塊或少一塊。

事件證據

這一欄的門檻是:別人不看你的結論,光憑這幾格就能把同一筆交易翻出來自己重讀一遍。

  • 鏈與合約地址,或 Solana 這一側的 mint 地址,原樣抄
  • 交易雜湊
  • 實際呼叫的函式或指令:_burn、burnFrom、Burn、BurnChecked,或者只是一筆 transfer
  • 事件的 from、to、value 分三格記;to 是非零地址時寫成「移轉至該地址」,不寫「銷毀」
  • value 用鏈上原始單位,decimals 另記,換算結果單獨一行
  • value 是零的那一筆照樣有事件,標成零值轉帳,不進數量那一格

控制證據

這一欄最常只填一半:簽出交易的地址和餘額變少的地址可以是兩個人,分兩格寫才看得出這一筆憑什麼成立。

  • 這筆交易由誰簽出
  • 憑什麼簽:本人餘額、allowance、delegate,或 permanent delegate
  • 事後供應還有沒有上升的路徑:mint_authority 是否仍在、合約是否留有鑄造入口
  • 這一欄取不到的部分照實寫未取得,不用「應該沒有」代替

時間

時間欄本身不證明任何因果,它只負責把兩次讀數釘在可以互相比較的位置上。

  • 交易所在的區塊高度或 slot
  • 前一次讀數的高度、後一次讀數的高度,兩格分開填
  • 觀察頁面的時間,跟鏈上高度分開記
  • 兩次讀數之間若還有其他交易,補一句,別讓總量差獨佔功勞

受影響的供應欄位

最後一欄決定結論的措辭能寫到多重:這一欄沒填出某個供應欄位下降了多少,前面三欄合起來也只描述了一次移轉。

  • totalSupply 或 mint 的 supply 有沒有下降,下降多少
  • 或者只有某個地址的餘額變動,總量沒動
  • cap 這一格是否未動
  • 供應商頁面上的供應量標「另查,未由本次事件證明」;各家供應商如何認定「永久銷毀」,本版未核,不在這裡下結論

兩條界線也劃在這一欄上。協議層原生幣的銷毀機制與本文討論的代幣合約不是同一套,本版未核,不在這裡展開;多鏈代幣在一條鏈上讀到的扣減,說明的也只是那條鏈上那個合約的狀態,其他鏈各自另記一份。

常見問題

代幣被送進公開的銷毀地址,總供應是不是就少了?

要看那個地址是不是零地址。OpenZeppelin 文件對 transfer 的要求寫明 to 不能是零地址,能正常收到代幣的地址就不是零地址,餘額轉過去之後仍計在 totalSupply 裡。這一步由條文推出,屬於本文的看法。真正對應供應扣減的簽名是 Transfer 事件的 to 為零地址且總供應下降,兩項要一起看。

合約裡有 burn 函式,是不是代表隨時會有人銷毀?

burn 與 burnFrom 來自 ERC20Burnable 擴充,它們存在只說明這個入口被寫進去了。誰能呼叫、有沒有被呼叫過,是另外兩個問題。burnFrom 還額外要求呼叫者持有足額 allowance。

為什麼銷毀了很多次,供應量看起來沒怎麼變?

事件筆數跟數量是兩回事。零值轉帳依規範也要發 Transfer 事件;flash mint 這類機制的鑄與毀成對發生在同一筆交易之內,結束後總量回到原處。逐筆看過 value 才能換算。

供應商頁面顯示的總供應量已經扣掉銷毀了,還需要自己看鏈上嗎?

各家供應商如何認定「永久銷毀」,本版未核,本文不對供應商的方法作任何判斷。兩邊記成兩欄、各自標明來源與觀察時間,是這份紀錄採取的做法。

代幣寫著「永久銷毀」,紀錄裡能這樣寫嗎?

這四欄支持不了「永久」這兩個字。填滿之後能寫的說法有固定形狀:在某個高度上,某筆交易呼叫了某個函式或指令,某一個供應欄位變成了某個值。Solana 官方文件裡確實有 permanently 這個詞,但那句話說的是這一次扣減本身不會被回滾,不等於供應水平從此不再上升——後者由 mint authority 還在不在決定,EVM 那一側同樣要回到鑄造函式與權限設定去讀。

同樣推不出來的還有兩類。一類是意圖:紀錄描述的是一次已經發生的狀態變化,它不說明為什麼發生,也不說明往後會不會再發生同樣的事。另一類是總量以外的分布:某一格供應欄位變小,不告訴你剩下的部分落在誰手上、集中程度有沒有變化,那要另起一輪讀取。

所以這份紀錄裡最該記住的一句是:銷毀這一欄回答不了供應會不會再上升。

內容來源

  • EIP-20: Token Standard發布者: Ethereum Improvement Proposals查閱日期:
  • OpenZeppelin Contracts 5.x — ERC20 API發布者: OpenZeppelin查閱日期:
  • Solana Docs — Burn Tokens發布者: Solana Foundation查閱日期:
  • Solana Docs — Tokens發布者: Solana Foundation查閱日期:
  • ethereum.org — ERC-20 Token Standard發布者: ethereum.org查閱日期: