###### tags: `z-institute` `上課筆記` `Solidity` `作業 # Week7 Group HW ## 團體開發實作作業 1. 完成畢業專案 User flow chart,用 [https://whimsical.com/](https://whimsical.com/) 或其他工具繪製 2. 下次上課會檢查畢業專案的智能合約進度 <!-- ## W4討論: * 選擇以太幣/matic幣/AA去付款 * 沒有刮中,銘謝惠顧->得到NFT可以有個機率,那個機率可以很低,例如100人沒有得到一個NFT的話,那合約裡就集了10個可以被刮到的,像現在大樂透的做法 * 刮中可以換錢或收藏 * 數量固定10-20個,攤出來給大家看獎品,刮到一個補一個,銷毀一個補一個 ->改成每多10人進來刮,就生成一個 * 討論如何可以穩定輸出固定量NFT * 刮刮樂裡面顯示的是NFT圖 * 看能不能結合預言機,然後提供兩種幣的兌換->必須先存有足夠量的幣才能兌換 -> 可以接Uniswap的合約,然後把以太幣賣成matic幣,然後再換給買家 * 使用到token standard ERC721 *https://etherscan.io/address/0xff9c1b15b16263c61d017ee9f65c50e4ae0113d7#code ### 上禮拜修正: * 每多10人進來刮,就生成一個NFT * 預言機保留至最後時現階段決定 * interface修改 * 輸出固定量NFT的實現 ### 討論結果 1. 中獎機率低(20%-30%) 2. 兌換真錢後保留 nft 3. 中獎了,就贖回買 nft 的錢,然後保留原來的 nft, 但如果不贖回,就可以 level up nft 4. 兌換真錢後,nft 變暗底 6. 嘗試去中心化的 svg 但圖就不會太複雜 --> <!-- https://github.com/ZigmaF/Ticket-Booking-System/blob/main/.deps/npm/%40openzeppelin/contracts/token/ERC721/ERC721.sol --> <!--https://github.com/ZigmaF/Ticket-Booking-System --> <!--![](https://i.imgur.com/Y37i0jb.png)--> <!-- ![](https://i.imgur.com/qAEL6Xd.png) --> <!-- cotract: 刮刮樂(買賣,是否終獎、兌換(變暗底)、機率(是否要猜開)) NFT(MINT ,burn) 預言機(取得隨機數) 處理svg圖 --> --- ## Week7討論 ### 目的: 更換project ### 主旨: 訂票系統 ### 原因: 傳統系統使用人數上中心化伺服器的使用人數比較佔優勢,但存在故障的風險。 區塊鏈平台處理大量交易和流量,更穩定,隨著人數增加,交易費用與時間增加,可能可以有效增加黃牛的成本。 ### User flow chart ![](https://i.imgur.com/gavtaiZ.png) ``` // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // User 包括賬戶餘額、訂票歷史等 contract User { address public owner; uint public balance; uint[] public orderIds; // key: 訂單 ID / value: Order mapping(uint => Order) public orders; // 訂單 struct Order { uint id; // 訂單 ID uint timestamp; // 下單時間 address seller; // 第三方賣家地址 uint price; // 訂單價格 uint amount; // 訂單數量 bool canceled; // 訂單是否已取消 } // 專案初始化,建立 User 合約 constructor() { owner = msg.sender; } // 存款 function deposit() public payable { balance += msg.value; } // 提款 function withdraw(uint amount) public { require(amount <= balance, "餘額不足"); balance -= amount; payable(owner).transfer(amount); } // 購買門票,創建一個新的訂單 function buyTicket(address seller, uint price, uint amount) public returns (uint) { require(amount > 0, "購買數量需大於 0"); require(price > 0, "門票價格需大於 0"); require(balance >= price * amount, "餘額不足"); uint id = orderIds.length + 1; Order memory order = Order(id, block.timestamp, seller, price, amount, false); orders[id] = order; orderIds.push(id); balance -= price * amount; return id; } // 取消訂單 function cancelOrder(uint id) public { require(msg.sender == owner, "您不是訂單擁有者"); require(orders[id].id == id, "訂單不存在"); require(!orders[id].canceled, "訂單已取消"); orders[id].canceled = true; balance += orders[id].price * orders[id].amount; } } ``` 參考資料:https://creately.com/guides/flowchart-guide-flowchart-tutorial/ --- user.sol ``` // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract User { // 使用者 struct userData { uint userId; // 使用者 ID uint timestamp; // 使用者創建時間 address userAddress; // 使用者地址 uint identity; //使用者身份 1.平台商(我們)/2.售票活動商/3.消費者 } uint userId; // userId 需要寫入 userData 嗎 mapping (address => userData) public users; constructor() {} // ::todo // 需要判斷使用者身份為何 // create user function createUser(){} // delete user function deleteUser(){} } ``` order.sol ``` // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Order { // 訂單 struct orderData { uint orderId; // 訂單 ID uint timestamp; // 訂單時間 address buyer; // 買家地址 uint price; // 訂單價格 uint amount; // 訂單數量 bool canceled; // 訂單是否取消 } uint orderId; mapping (address => orderData) public orders; constructor() {} // ::todo // orderList } ``` ticket.sol ``` // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Ticket { // 票 struct ticketData { uint ticketId; // 票 ID uint timestamp; // 購票時間 address buyer; // 買家地址 uint price; // 票價格 uint amount; // 票數量 bool use; // 票是否使用 } uint ticketId; mapping (address => ticketData) public tickets; constructor() {} // :: todo // 加價購 NFT // :: question // 1. 如何存取一個人擁有不同活動場次的票(mapping可以嗎) // 2. 主辦提款是放在這裡嗎 // 預期要做的function // 買票 function () external payable{ buyTikcet(); } function buyTikcet() private{} // 退票 function cancelTicket(address event, uint price, uint amount) external {} // 使用票/驗票 function verify(bytes32 _ticket) external view returns(bool){} //平台方提款 function withdraw() external{} } ``` event.sol ``` // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Event { // 活動 struct eventData { uint eventId; // 活動 ID uint timestamp; // 活動時間 address seller; // 第三方賣家地址 uint price; // 活動價格 uint amount; // 活動數量 bool online; // 活動是否上線 } uint eventId; mapping (address => eventData) public events; constructor() {} // ::todo // 創建活動 // 撤下活動 } ```