# 票券上鏈系統
`2020.01.16 refactor`
`2019.11.20 api-v3`
`2019.10.07 modified`
`2019.10.04 modified`
`2019.09.03 modified`
`2019.07.23 created`
---
[TOC]
---
## <span style="color:red">API</span>
### Public
#### Get Server Timestamp `GET /api/now`
Response:
```javascript
{
"timestamp": 1570248114563, // A Number representing the milliseconds elapsed since the UNIX epoch.
"ISOString": // A string representing the given date in the ISO 8601 format according to universal time.
}
```
### Authorized
---
* header: `X-TICKET-TOKEN: <token>`
* header: `X-TICKET-HMAC: <HMAC>`
* HMAC Example:
```javascript
// Node.js
const hmac = require('crypto')
.createHmac('sha512', keyStr)
.update(payloadStr)
.digest('hex')
```
```javascript
// Javascript
const hmac = require("crypto-js")
.HmacSHA512(payloadStr, keyStr)
.toString(require("crypto-js").enc.Hex)
```
```php
// Php
$hmac = hash_hmac('sha512', $payload_str, $key_str);
```
Say, ... https://www.freeformatter.com/hmac-generator.html#ad-output 
`185beceee65a5ed7e43f7cc98530bfab1b0d00679488a47225255d04594fd7f17ed6908e7a08df57ac14c9e56c2fdef83ee9adaf9df2ff9f61465898c5d78c00`
---
#### App Url Format
* https://ipfs.io/ipfs/QmQDDrBT2mCPUW8A6a43xeAkP6GKqHTRQ3dFUK2YQ1oLuz/?sn=0000000000
---
#### Create A new Vendor `POST /api/{user}/vendors`
Request
```javascript
{
"name": "My Non-Fungible Tickets",
"symbol": "MNFT"
}
```
Response
```javascript
{
"name": "My Non-Fungible Tickets",
"symbol": "MNFT",
"transaction": "...",
"contract": "..."
}
```
#### Get A Vendor
Path: `Get /api/{user}/vendors/{contract}`
#### Get All Vendors
Path: `Get /api/{user}/vendors`
#### Create A New Ticket
Path: `POST /api/{user}/tickets/{contract}`
Request
```javascript
{
"info": {
"id": '34', // **商品編號** (string represets a decimal number)
"name": "田馥甄 2020 演唱會",
~~"cap": "2000",~~ // **Removed**
"url": "https://...",
"inception": "2019-11-19T10:58:29+08:00",
"expiration": "2019-11-19T10:58:29+08:00"
}
}
```
Response
```javascript
{
"info": { ... },
"transaction": "...",
"state": { ... },
"ticketId": 4321
}
```
#### **Update A Ticket**
Path: `PATCH /api/{user}/tickets/{contract}/{ticketId}`
Request
```javascript
{
"data": [
{
"sn": "0000000000",
"owner": "...",
"sold": "2019-11-19T10:58:29+08:00",
"redeemed": "...",
"invalid": "..."
},
{
"sn": "0000000001",
"owner": "...",
"sold": "2019-11-19T10:58:29+08:00",
"redeemed": "...",
"invalid": "..."
},
...
]
}
```
Response
```javascript
{
account: 'dev',
contract: '0xd6aE7257CC4C24eC5272D1138A7eF5f9B30eDb8D',
info:
{ pn: 'fe40298c',
name: '田馥甄 97fb 演唱會',
cap: '25',
uri: 'https://350f6a2cba1e242e2018b5996b629143',
inception: '2020-01-19T10:58:29+08:00',
expiration: '2020-01-19T10:58:29+08:00' },
meta:
{ name: '田馥甄 97fb 演唱會',
contract:
'https://ropsten.etherscan.io/token/0xd6a...',
updated_at: '2020-01-14T16:16:02+08:00' },
state:
{ ipfs:
'https://ipfs.io/ipfs/QmRK8or6msts5xoJZ5Gx3J8yx5RYv6Z3ZB4yAXbn5NtPes',
updatedAt: '2020-01-16T11:48:56+08:00' },
ticket_id: 0,
transaction:
'0x6dbdad55da2fec4d035edc407901c9553b4db068e4c442302e1b265a7799e57f',
last_transaction:
'0xfadf616deaf8f7863e5966791ca80304051d3a07e8e614927efb91696529d8b0' }
}
```
~~#### Get A Ticket~~
Path: `GET /api/{user}/tickets/{contract}/{ticketId}`
#### Get All Contract Tickets
Path: `GET /api/{user}/tickets/{contract}`
#### Get All Tickets
Path: `GET /api/{user}/tickets`
#### Get A Transaction
Path: `GET /api/{user}/transactions/{transaction}`
#### Get All Transactions
Path: `GET /api/{user}/transactions`
#### Get Wallets Info
Path: `GET /api/{user}/wallets`
## 系統預定規格概述
```mermaid
graph TD
api-user --- server
resp-api --- full-node
subgraph Ethereum Blockchain
contracts --- full-node
end
subgraph Cloud Server
resp-api --- server
end
style full-node fill,stroke:#f6,stroke-width:px,stroke-dasharray: 5, 5
style api-user fill,stroke:#f6,stroke-width:px,stroke-dasharray: 5, 5
```
本專案之系統包含了
1. 乙太坊上智能合約軟體;
2. 與 1 互動溝通的伺服器軟體 (REST API);
3. 運行 2 的伺服器架設代管;
4. 系統文件。
軟體包合兩部份,其一為使用乙太坊區塊鏈技術的上智能合約;其二為用來與區塊鏈互動的一 REST API,分別描述如下:
1. 乙太坊上一個或多個智能合約軟體 (*Smart Contract*):功能包含
* Ownership:
* 特定權限的乙太帳戶才能執行指定操作;
* 合約所有權轉移功能。
* Operation:
* 產生新票種、鏈上記錄該票種必要資訊。
* 產生新票卷、鏈上記錄該票卷必要資訊、鏈上更新票該卷狀態。
* 該合約應在測試階段部署在乙太坊公開測試鏈 (Ropsten Testnet);在運營階段部署在乙太坊公開主鏈 (Mainnet)
* Mainnet Browser: https://etherscan.io/
* Ropsten Brower: https://ropsten.etherscan.io/
2. 與智能合約互動的 REST API (a backend software):功能包含
* 能夠對接上述智能合約,讀取合約、寫入合約、追蹤交易。
* 管理管理者的乙太帳戶、私鑰、乙太幣。
* REST API Routes
* 建立一新票種 (create/post)
* 查詢特定票種 (get/get)
* 更新特定票種狀態 (update/patch)
* 發特定票卷 (mint token)
* 更新特定票卷狀態 (set sold/redeeemed/invalid state)
* 查詢 transaction 結果/確認數 (get)
* REST API Authentication
* Token: 識別 API USER 身份
* Secret: 驗證 API USER 身份
* Timestamp: 防止重送攻擊
3. 伺服器架設、代管部份:
* 除 REST API 伺服器外另需一乙太坊的區塊鏈全節點 (Full Node) 將選用穩定可靠的第三方乙太全節點服務 (如 https://infura.io/ )。伺服器運行費用另計。
4. 文件。除軟體服務外,本系統應包含說明文件,並區分為
* 技術文件 (Technical Specification):技術人員使用,包含完整規格、系統原理、運作方式,以供未來技轉或專案重啟使用。
* 操作文件 (Operational Specification):非技術人員使用,包含基本操作、系統概觀、維運成本概算、金流/私錀管理等注意事項。
### <span style="color:red">ITEMS</span>
* 票種 (TICKET) 上鏈資訊? (活動卷、商品卷)
- [ ] name (票種名稱 e.g. "United State Dollar")
- [ ] symbol (票種縮寫 e.g. "USD")
- [ ] info:
- [ ] id (票種編號)
- [ ] cap (發行張數)
- [ ] url (web/ipfs 網址-可放 logo 圖等)
- [ ] class ({ 活動卷、商品卷 ... })
- [ ] start (開始日期)
- [ ] expiration (結束日期)
* 票券 (TOKEN) 上鏈資訊?
- [ ] token id (流水號, 0, 1, 2, 3, ...)
- [ ] owner:
- [ ] 方案一: uid 明碼 (e.g. `5dc147-b4b444-1b3fbf-43f450`)
- [ ] 方案二: uid+hash (e.g. `c89ba2b2caf8b....`)
- [ ] 方案三: eth addr (e.g. `0x5774ae4bD....`) (ps. the private key will be generated by HD Wallet architecture, with node path = uid) (In brief, a `seed` + `uid` -> `private-key` -> `public-key`=address)
- [ ] states: timestamp
- [ ] 1. sold (已上鏈) `2019-11-06T07:52:35.341Z GMT+0`
- [ ] 2. redeemed (已使用) `2019-11-06T07:52:35.341Z GMT+0`
- [ ] 3. invalid (已作廢) ` `
* <span style="color:blue">stateA (信託狀態)</span>: 未使用、已使用、已作廢、請款中、已請款
* <span style="color:blue">stateB (票卷狀態)</span>: (已上鏈)、未使用、已使用、已作廢、已過期
* <span style="color:blue">stateC (平台請款狀能)</span>: 無、(可請款)、已作廢、請款中、請款完成、請款失敗
* 鏈上操作數量級 (頻率/個數)
- [ ] `POST /tickets` (name, symbol, info)
- [ ] `PATCH /tickets/:contract/batchMint` (<span s style="color:red">tokenIds, toAddresses,</span> sold)
- [ ] `PATCH /tickets/:contract/setStateRedeemed` (tokenId, timestring)
- [ ] `PATCH /tickets/:contract/setStateInvalid` (tokenId, timestring)
* 消耗費用
* GCP 費用: $25~$50/M
* INFURA 費用:
* $0/M: 100K Request / Day
* $50/M: 200K Request / Day
* TRX 費用: https://ethgasstation.info/calculatorTxV.php
* gas: mint 100 張: 4929764
* Blocks
```mermaid
graph LR
Contract-Matrix -->|created| Contract-TicketA
Admin -->|owner| Contract-Matrix
Admin -->|owner| Contract-TicketA
Api-Server -.->|priv| Admin
Api-Server -.->|priv| Admin
Minter -.- Contract-TicketA
Minter -->|mint| user1
Minter -->|mint| user2
Minter -->|mint| user3
Operator -->|transfer|user1
Operator -->|transfer|user2
Operator -->|transfer|user3
style Contract-Matrix fill:#f9f,stroke:#333,stroke-width:4px,coler:#333,font-size:5px
style Contract-TicketA fill:#f9f,stroke:#333,stroke-width:4px
```
### Ref
* https://drive.google.com/file/d/0B-T4BwVnxLmOdmlXTTREcUNCcHE0RzdRR1lMaF92THFUS1U0/view?usp=sharing
* 
## Reference
### 2020-01-16
- [ ] Ticket sn
- [ ] Vendor Identification (`SYMBOL`)
- [ ] Uncapped Ticket
- [ ] ipfs front end
- [ ] DeERC721
### DEMO
* account
* network
```bash=
npx truffle compile
# NAME, SYMBOL, MORE_OPERATOR
npx truffle migrate -f 2 --to 2 --network ropsten
# MATRIX_ADDR
npx truffle-flattener ./contracts/Matrix.sol > ./flat.sol
sed -i 's/pragma experimental ABIEncoderV2;//g' flat.sol
{ echo 'pragma experimental ABIEncoderV2;'; cat flat.sol; } | tee flat.sol > /dev/null
scp x240-gcpdev:~/ticket/contract/flat.sol .
mv ./flat.sol $USERPROFILE/Desktop
# verification
npx truffle exec ./scripts/tests/mintANewToken.js --network ropsten
npx truffle exec ./scripts/tests/updateATokenState.js --network ropsten
```
###### tags: `SPEC` `BITCOIN`