# Beard | C0041103 - 第 4 週作業 ## 發行NFT 並有盲盒功能 - Contract Address: https://goerli.etherscan.io/address/0x984926718f7a9956594349f442311adb661625bb - gist: https://gist.github.com/BeardYing/87bb554a828b49ef6aded48d016717db - goerli.looksrare: https://goerli.looksrare.org/collections/0x984926718f7A9956594349f442311Adb661625Bb #### 作業需求 > 朋友想要請你發行 NFT,希望採用盲盒模式來增加神秘感,購買時並不知道裡面是什麼,等到一定的時間,盲盒就會開啟,才會知道買的 NFT 是什麼樣子 > - 引用 ERC721 標準,可 mint 你的 NFT > - 需提供 Looksare Testnet Goerli NFT項目網址 > - 宣告控制盲盒開關的參數 revealed > - 寫一個 switchRevealed function 可以控制盲盒開啟與否 > - 開關控制會讓 tokenURI 的值有所不同 > - 若 revealed 是 true,tokenURI 設定解盲後的 json > - 若 revealed 是 false,tokenURI 設定尚未開盲盒的 json #### 說明 - 由於製作的功能有白名單/公售功能,所以部署合約後,直接切換成 public sale - 比較特別在於,這專案撰寫時,把setBaseURI 跟 解盲寫在一起,為了避免解忙時手忙腳亂,也可避免太早上傳正式圖片洩漏。 - 設定盲盒圖: <code>*setBaseURI(ipfs://[盲盒圖片的 json CID], false)*</code> - 解盲: <code>*setBaseURI(ipfs://[圖片的json資料夾 CID]/, true)*</code> - 其餘說明有另外整理於:[KTOne NFT發行筆記](https://hackmd.io/hjrNHSj-T3uZAd3pK7xVgg) - 盲盒截圖 ![](https://i.imgur.com/uKzOzay.png) - 解盲截圖 ![](https://i.imgur.com/vOvNJpE.png) ## 用 chainlink VRF 產生隨機數來實作樂透 - Contract Address: https://goerli.etherscan.io/address/0x6a897f2616729dc28fb7bd1e834ec663a0526484 - gist: https://gist.github.com/BeardYing/3fd86441ccabf674e2e68d7abed60b57 - 基本題:Y - 進階題:Y - (有些許改版,不過應該是有達到基本/進階版想要的功能效果) #### 作業需求 > ##### 基本題 > - 多人可以參與這期投注,該期投注的總金額會作為當期樂透發放獎金 > - 實作一個參與樂透 enter Function,參與者必須投入 0.001 ether 才能參與這期樂透(提示:可定義 enter function,並用 payable 接收 eth) > - 可以知道參與這期樂透有多少人 > - 可以知道這期總獎金額目前是多少 ether > - 合約需定義 getRandomNumber Function,必須使用 ChainLink VRF 預言機來取得隨機數 > - 部署合約者是 owner > - 開獎條件:本期樂透總獎金必須累積到某個金額(例:0.01 eth),owner才可開獎。 > - 幸運得主可獲得樂透本期總投注獎金 100% > ##### 進階題 > - 設定每一期樂透開獎時間限制(例如10分鐘)開獎一次 若開獎時間未到,owner 無法進行開獎 若已超過開獎時間,未累積到指定開獎金額(例:0.01 eth),則退款給本期所有投注者 #### 作業說明 - 本次作業稍加調整成貼近樂透的投注方式,並且盡可能實作原本題目的需求。 #### 遊戲方式與規則 1. 一次只有一個樂透遊戲啟用,可投注號碼 1 ~ 5 (初始化時可設定) 2. 若未達到最低標準,進行退費 3. 沒中獎,獎金累積到下一期,直到中獎為止 4. 當期中獎者根據 當期中獎+累積獎金 依照投注比例平分給中獎人員 #### 程式說明/操作 1. 取得目前投注總金額: <code>*lotterys[lotterRound].pot* </code> 2. 下注: <code>*entry(uint256 _no, uint256 _betCount)*</code> - *uint256 _no* : 投注號碼 - *uint256 _betCount* : 想投注的數量(與中獎分潤有關) 3. 合約所屬者可以使用: - <code>*getWinnerProcess()*</code> - 若是投注不足,會直接退款 - 若是投注超過限額,開始對預言發出中獎隨機碼請求。 - <code>*startNewLottery()*</code> - 若是本期的投注金額為 0,而且投注時間已過期,則 Owner 可以新建樂透。 - 若是還有在進行中或是尚未開獎的樂透遊戲,無法新建樂透 - <code>*reward()*</code> - 若沒人中獎將獎金放入 potPool,等待下次人員中獎時,取出平分。 - 若有人中獎,依據投注金額比例分配獎金 4. 處理順序:<code>*getWinnerProcess()*</code> ---[等待預言機回傳]--> <code>*reward()*</code> ---> <code>*startNewLottery()*</code> #### 試玩看看 - 第一期投注 1號 3號各一注,結果開獎為2號,沒中獎,獎金0.002納入 potpool ![](https://i.imgur.com/dFHkL6w.png) - 第二期沒人下注,直接開立新局第三期 - 第三期:兩人包牌 - (0x00c5) 1~5各買1注 - (0xadf8) 1~5各買2注 - 總獎金來到:0.002 + 0.005 + 0.010 = 0.017 eth ![](https://i.imgur.com/GH1swur.png)<small><i> - 由於沒截圖到,直接利用最後一筆投注(block= 7484811)查看目前合約變化</i></small> - 中獎號碼為3號,獎金分別投注者為 - 0x00c5 1注 / 0xadf8 2注 ,可利用 function 查詢 ![](https://i.imgur.com/OEs3ZUP.png) - 計算分配獎金 - 0x00c5 可獲得 (0.017 / 3) * 1 = 0.00566666667 ether - 0xadf8 可獲得 (0.017 / 3) * 2 = 0.01133333333 ether - 在txn紀錄中,可以看見的變換狀態:[Txn Status](https://goerli.etherscan.io/tx/0xfd840d7ce70b9cf33d7afbc776aa24ef488f83391b2c5d04ba6de371bce39064#statechange) ![](https://i.imgur.com/GMoK0mf.png) - 建立第四期樂透,並且測試投注額度不足退款,可看到 Start New 後僅有一筆 0.001 eth 的 Entry 請求,故未達到最低門檻:0.002 eth ![](https://i.imgur.com/OyDvMGw.png) - 在Get Winner Process時,判斷未達最低門檻,進行退款 ![](https://i.imgur.com/FPBdgdq.png) ###### tags: `Solidity 工程師實戰營第 4 期`