---
# System prepended metadata

title: Week7 Group HW
tags: [上課筆記, z-institute, Solidity]

---

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