嘟嘟房NFT鑄造出包!智能合約到底哪裡出了問題?
隨著 NFT 的觀念及討論逐漸在台灣流行,許多本土業者及團隊將業務範圍擴展至此領域,但畢竟產業尚未成熟,智能合約的撰寫、Discord 社群的經營等等皆不是一般傳統業者能用過往的方式處理的,也因此產生許多爭議問題。今日,要談的主角是全台停車場龍頭「嘟嘟房」在 NFT 發行時的合約問題,究竟哪部分有問題導致大量鑄造失敗?
(本篇轉載自 FULY.AI 智能投資機器人創辦人 Rex Chen,原文請見)
嘟嘟房 NFT 出包事件
嘟嘟房 3/11 早上 10:00 開放白名單可以去 mint,但是幾乎所有人有白名單的全部都 mint 失敗!
廣告 - 內文未完請往下捲動
這是嘟嘟房的智能合約地址:
https://etherscan.io/address/0xae122962331c2b02f837b2aa501d3c5d903ed28a#code
根據合約可以看得出來他的 preSaleMint,有做檢查判斷是否 isWhitelisted。
這是這次出包問題的核心,isWhitelisted 的 function。
而真正儲存在區塊鏈的變數是 whitelistedAddresses,他是一個 Array 裡面塞滿了所有的白名單。
在智能合約裡面用 for loop 去一個一個檢查資料,如果當 array 資料少的時候沒什麼太大問題,但如果白名單增長了,那問題可就大了。
根據合約 transaction 可以看出所有的白名單有 898 筆,寫入這些白名單資料花費了 0.689 以太的手續費,真是爆多啊。
如果你運氣很好的你白名單在前面的順位,恭喜你可以用很低的 gas fee 去 mint 到,如果你在後面的話你就衰小了。
這些是剛開始所有的失敗交易紀錄,其實不知道為什麼有些人要偷跑先mint,都有白名單了 XD,但他這個項目比上次偷跑賣光的 Yolocat 09 哥合約好一點,他有設定 preSaleStart <= block.timestamp,所以基本上是不可能可以偷跑去 mint。
由於他有設定 preSaleStart <= block.timestamp
這時間換算台灣時間就是早上十點。
這是第一筆真的交易失敗的交易紀錄,他是在白名單裡面的258號,算是比較中間的,這時候的 Gas Limit 是設定 420,000,因為 Gas Limit 設定太少,所以他 out of gas。
這是第一筆成功 mint 到的人,他在白名單裡面編號是第 4 號,運氣超好,所以他只有花了 16.93 美的手續費就 mint 到了,以太坊最近很冷清,這時候的 Base gas fee 才 32 Gwei,這樣子的手續費是正常的。
我們來看後來項目方手動調整到 Gas Limit 兩百萬,還是有人失敗,因為他在白名單裡面編號是869號,真是有夠衰小,花了144.99美的手續費,還是 out of gas。
所以問題是什麼呢?
- Gas Limit 設定太小是第一點,但正常自己用 metamask 都可以進階去手動調整,應該不是什麼太大問題
- 真正的問題在用 for loop去爬 array,造成越後面順位的人手續費就越高,會是等比級數的成長,很恐怖,前面的人就很lucky
那這樣的問題該怎麼解決呢?比較簡單的做法就是不要用 array 去存,用一個 mapping 去存這個地址是這個地址是白名單。
然後判斷的時候直接判斷,就不用一個 for loop 去跑。
但缺點是設定白名單一樣成本很高,但至少不會造成用戶去 mint 的時候成本很高!
所以現在主流做法都是用 merkle tree 的方式來實作白名單,好處是修改名單方便,也不用這麼高的手續費,小弟最近也剛研究完而已,有任何寫錯的地方都歡迎技術交流。