可鑄造 NFT 中的隨機值
我過去讀過和寫過簡單的智能合約,但我對在交易中獲取隨機數據還比較陌生,由於 EVM 的確定性,這似乎比我想像的要難。
我正在開展一個 NFT 項目,其中將有幾個稀有類別的 NFT。*稀有度需要在薄荷上隨機分配。*讓我們保持簡單,為了舉例,假設總供應量為 100 件,其中 5 件很少見。
我對此進行了一些研究,發現以下內容:
送出和揭示不是一種選擇,因為它不是彩票。我需要把所有東西都放在薄荷上並冷凍。
我無法從使用者那裡獲得隨機輸入:即使我在 JS 中提供了一個帶有隨機生成的良好 UX,客戶端隨機生成顯然是不安全的。
我不能簡單地放棄鏈上隨機性並在我身邊產生隨機稀有性:
- 如果我將 NFT 數據放到 IPFS 中,每個 NFT 都可以提前訪問它們,顯然不是一個選項。
- 如果我將元數據 URI 指向我控制的某個 HTTP 伺服器,使用者將需要在公平分配上完全信任我,這是我不想要的。我需要不信任的東西。
我不確定諸如 Provable 或 Chainlink 之類的外部預言機,它們似乎使用回調進行隨機生成,不確切知道如何以這種方式進行。它也是收費的,我更喜歡免費的,但如果這是我可以支付的唯一選擇。
我還在https://etherscan.io/address/0xff9c1b15b16263c61d017ee9f65c50e4ae0113d7#code檢查了 LOOT 的合約程式碼。它似乎有一個這樣定義的隨機函式:
function random(string memory input) internal pure returns (uint256) { return uint256(keccak256(abi.encodePacked(input))); }
它似乎在輸入上採用了 KECCAK-256,它本身只是一些硬編碼字元串和令牌編號的連接+打包形式。我認為從攻擊者那裡獲得稀有薄荷糖根本不安全,但如果我錯了,請糾正我。
最好的方法是什麼?我知道之前有人問過生成隨機數,但許多問題要麼是關於彩票(可能會在未來揭示),要麼是關於同樣罕見但只是隨機的東西的收藏。使用類似於 Loot 合約的東西是安全的,還是使用 oracle 進行 2-process 或 commit/reveal 唯一的好方法?
我最終做了一個兩階段的薄荷糖:
- 在第一階段,代幣被鑄造出來,它們的塊號儲存在鏈上,但它們的價值/稀有度並不確定。
- 在等待至少 1 個塊但不超過 256 個塊後,會進行第二次呼叫,以根據 NFT 首次鑄造的塊之後的下一個塊的塊雜湊計算隨機性。
缺點是它是兩階段的。使用者需要兩筆交易,每筆交易都需要花費一些氣體,並且需要在 256 個區塊內完成,否則 N+1 的區塊雜湊將為零。(我通過將這種情況預設為我項目中最低稀有度(最常見)的層來抑制)