###### 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 -->
<!---->
<!--  -->
<!--
cotract:
刮刮樂(買賣,是否終獎、兌換(變暗底)、機率(是否要猜開))
NFT(MINT ,burn)
預言機(取得隨機數)
處理svg圖
-->
---
## Week7討論
### 目的:
更換project
### 主旨:
訂票系統
### 原因:
傳統系統使用人數上中心化伺服器的使用人數比較佔優勢,但存在故障的風險。
區塊鏈平台處理大量交易和流量,更穩定,隨著人數增加,交易費用與時間增加,可能可以有效增加黃牛的成本。
### User flow chart

```
// 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
// 創建活動
// 撤下活動
}
```