# NFTicket, Nigeria Sequence Diagram (V2) ## Smart Contract Architecture ![](https://i.imgur.com/G2t1WBg.png) ----------- ## Smart Contract Specification ### Nigeria Service Contract **storage** :::info * mapping: NFTicketId & credit * mapping: NFTicketId & presenter ::: **function (Presenter Related)** :::info * getPresenter(NFTicket_id) return (presenter_address) * **[internal]** setPresenter(NFTicket_id, presenter_address) ::: **function (Ticket Related)** :::info * createNewNFTicket(recipient_wallet_address) * presentTicket(NFTicket_id, presenter_address) * refundTicket(NFTicket_id, credit_amount, refund_receiver_address) return (token_amount) * verifyTicketOwner(verify_address, NFTicket_id) * request IERC721.ownerOf(NFTicket_id) * return NFTicket owner address * verify verify_address is the NFTicket owner address * verifyIsGetApproved(verify_address, NFTicket_id) * request IERC721.getApproved(NFTicket_id) * return approver address * verify approver address is verify_address ::: **function (Service Related)** :::info * **[Ticket Master(Backend) only]** cancelService(NFTicket_id, deduct_credit) * endService(Driver_wallet_address, Passenger_NFTicket_id, credit) ::: **function (Credit Related)** :::info * topUp(NFTicket_id, credit) * getCreditBalance(NFTicket_id) return (credit_balance) * **[admin & this contract only]** setCreditBalance(NFTicket_id, credit) * **[admin & this contract only]** addCredit(NFTicket_id, credit) * getCreditBalance(NFTicketid) * calculate credit balance after add credit * setCreditBalance(NFTicket_id, credit balance after addition) * **[admin & this contract only]** deductCredit(NFTicket_id, credit) * getCreditBalance(NFTicket_id) * calculate credit balance after deduct credit * setCreditBalance(NFTicket_id, credit balance after deduction) ::: ### Ticket Master Contract **storage** :::info * service contract whitelist ::: **modifier** :::info * inServiceContractWhitelist ::: **function** :::info * **[Owner only]** setServiceContractWhitelist(contract_address) * **[Owner only]** removeServiceContractWhitelist(contract_address) * **[whitelist service contract only]** mintNFTicket(recipient_wallet_address) return (NFTicket_id) * **[whitelist service contract only]** transferERC20TokenToWallet(wallet_address, ERC20_address, ERC20_token_amount) * **[whitelist service contract only]** transferNFTicketToOriginalOwner(original_owner_wallet_address, NFTicket_id) * **[whitelist service contract only]** distributeRevenueToPool(pool_owner_address, ERC20_address, ERC20_token_amount) ::: **Used OpenZeppelin function** :::info * ownerOf(NFTicket_id) return (owner_address) * approve(approver_address, NFTicket_id) msg.sender approve approver to transfer his/her NFT * transferFrom(from_address, to_address, NFTicket_id) * _transfer(from_address, to_address, NFTicket_id) * getApproved(NFTicket_id) return (approver_address) ::: ### ERC20 Token Contract **Used OpenZeppelin function** :::info * approve(spender_address, token_amount) return (bool) msg.sender approve spender to manage his/her token in certain amount * allowance(token_owner_address, spender_address) return (allowance_amount) the amount token owner allow spender to manage * transferFrom(from_address, to_address, token_amount) return (bool) * transfer(to_address, token_amount) return (bool) ::: ----------- ## Smart Contract Configuration (config when deploy) **Nigeria Service Contract** :::info * Price per credit * ERC20 token address (allow only one token) ::: **Ticket Master Contract** :::info * Base fee ::: ----------- ## Sequence Diagram ### passenger first register and get NFTicket :::success *correspond to Nigeria sequence diagram **01.sequence-diagram-passenger-connect-wallet*** ::: :::danger 不確定 passenger 是否要付 base fee,先以不用付 base fee 的情境設計 ::: ```mermaid sequenceDiagram participant BE as Backend participant SCSC as Nigeria Service Contract participant TMSC as Ticket Master Contract actor P as Passenger BE->>SCSC: request createNewNFTicket(wallet_address) SCSC->>TMSC: request mintNFTicket(wallet_address) TMSC->>TMSC: verify caller is inServiceContractWhitelist TMSC->>TMSC: verify payment >= base fee TMSC-->>P: mint NFTicket TMSC-->>SCSC: return NFTicket_id SCSC->>SCSC: setCreditBalance(NFTicket_id, 0) SCSC-->>BE: return success ``` ### passenger start journey (get Credit Balance) :::success *correspond to Nigeria sequence diagram **03.sequence-diagram-passenger-create-journey*** ::: ```mermaid sequenceDiagram participant FE as Frontend participant SCSC as Nigeria Service Contract participant TMSC as Ticket Master Contract FE->>TMSC: request ownerOf(NFTicket_id) TMSC-->>FE: return NFTicket owner address FE->>FE: verify passenger wallet address is the NFTicket owner address FE->>SCSC: request getCreditBalance(NFTicket_id) SCSC-->>FE: return NFTicket credit balance FE->>FE: verify NFTicket credit balance is sufficient ``` ### passenger start journey (present Ticket) :::success *correspond to Nigeria sequence diagram **03.sequence-diagram-passenger-create-journey*** ::: :::danger 如果是 passenger 自己 sign 的 transaction,不用帶 presenter 參數也沒關係, set meg.sender 當 presenter 也可以 ::: ```mermaid sequenceDiagram participant FE as Frontend participant SCSC as Nigeria Service Contract participant TMSC as Ticket Master Contract FE->>TMSC: request approve(Nigeria Service Contract address, NFTicket_id) TMSC-->>FE: return success FE->>SCSC: request presentTicket(NFTicket_id, passenger wallet address) SCSC->>SCSC: verifyIsGetApproved(Nigeria Service Contract address, NFTicket_id) SCSC->>SCSC: setPresenter(NFTicket_id, passenger wallet address) SCSC->>TMSC: request transferFrom(passenger wallet address, Ticket Master Contract address, NFTicket_id) SCSC->>SCSC: verifyTicketOwner(Nigeria Service Contract address, NFTicket_id) SCSC-->>FE: return success ``` ### passenger start journey cancellation (driver not found) :::success *correspond to Nigeria sequence diagram **03.sequence-diagram-passenger-create-journey*** ::: ```mermaid sequenceDiagram participant BE as Backend participant SCSC as Nigeria Service Contract participant TMSC as Ticket Master Contract BE->>SCSC: request cancelService(NFTicket_id, 0) SCSC->>SCSC: getPresenter(NFTicket_id) SCSC->>TMSC: request transferNFTicketToOriginalOwner(presenter address, NFTicket_id) TMSC->>TMSC: verify caller is inServiceContractWhitelist TMSC->>TMSC: _transfer(Ticket Master contract addrress, presenter address, NFTicket_id) SCSC->>SCSC: verifyTicketOwner(presenter address, NFTicket_id) SCSC-->>BE: return success ``` ### passenger start journey cancellation (cancel by passenger) :::success *correspond to Nigeria sequence diagram **03.sequence-diagram-passenger-create-journey*** ::: :::danger cancel fee 要給誰? ::: ```mermaid sequenceDiagram participant BE as Backend participant SCSC as Nigeria Service Contract participant TMSC as Ticket Master Contract BE->>SCSC: request cancelService(NFTicket_id, deduct_cancel_fee) SCSC->>SCSC: deductCredit(NFTicket_id, deduct_cancel_fee) SCSC->>SCSC: getPresenter(NFTicket_id) SCSC->>TMSC: request transferNFTicketToOriginalOwner(presenter address, NFTicket_id) TMSC->>TMSC: verify caller is inServiceContractWhitelist TMSC->>TMSC: _transfer(Ticket Master contract addrress, presenter addres, NFTicket_id) SCSC->>SCSC: verifyTicketOwner(presenter, NFTicket_id) SCSC-->>BE: return success ``` ### driver end journey :::success *correspond to Nigeria sequence diagram **06.sequence-diagram-driver-end-journey*** ::: ```mermaid sequenceDiagram participant FE as Frontend participant SCSC as Nigeria Service Contract participant TMSC as Ticket Master Contract participant ETSC as ERC20 token Contract FE->>SCSC: request endService(Driver_wallet_address, Passenger_NFTicket_id, credit) SCSC->>SCSC: deductCredit(Passenger_NFTicket_id, credit) SCSC->>SCSC: get Price per credit and ERC20 token address SCSC->>TMSC: distributeRevenueToPool(Driver_wallet_address, ERC20_token_address, credit * price per credit) TMSC->>TMSC: verify caller is inServiceContractWhitelist TMSC->>ETSC: approve(Driver_wallet_address, Original allowance + credit * price per credit) SCSC->>SCSC: getPresenter(NFTicket_id) SCSC->>TMSC: request transferNFTicketToOriginalOwner(presenter address, NFTicket_id) TMSC->>TMSC: verify caller is inServiceContractWhitelist TMSC->>TMSC: _transfer(Ticket Master contract addrress, presenter addres, NFTicket_id) SCSC->>SCSC: verifyTicketOwner(presenter address, NFTicket_id) SCSC-->>FE: return success ``` ### driver withdraw ticket(withdraw ERC20 token) :::success *correspond to Nigeria sequence diagram **10.sequence-diagram-driver-withdraw*** ::: ```mermaid sequenceDiagram participant FE as Frontend participant ETSC as ERC20 token Contract FE->>ETSC: request allowance(Ticket Master contract address, Driver wallet address) ETSC-->>FE: return allowance amount FE->>ETSC: request transferfrom(Ticket Master contract address, Driver wallet address, allowance amount) ``` ### passenger top up :::success *correspond to Nigeria sequence diagram **07.sequence-diagram-top-up*** ::: ```mermaid sequenceDiagram participant FE as Frontend participant SCSC as Nigeria Service Contract participant ETSC as ERC20 token Contract FE->>ETSC: request approve(Nigeria Service Contract address, token_amount) ETSC-->>FE: return success FE->>SCSC: request topUp(NFTicket_id, credit) SCSC->>SCSC: verify allowance >= credit * price per credit SCSC->>ETSC: request transferFrom(msg.sender, Ticket Master Contract, credit * price per credit) SCSC->>SCSC: addCredit(NFTicket_id, credit) SCSC-->>FE: return success FE->>SCSC: request getCreditBalance(NFTicket_id) SCSC-->>FE: return NFTicket credit balance ``` ### passenger refund ticket (get credit balance) :::success *correspond to Nigeria sequence diagram **08.sequence-diagram-passenger-refund*** ::: ```mermaid sequenceDiagram participant FE as Frontend participant SCSC as Nigeria Service Contract FE->>SCSC: request getCreditBalance(NFTicket_id) SCSC-->>FE: return NFTicket credit balance ``` ### passenger refund ticket (refund Ticket) :::success *correspond to Nigeria sequence diagram **08.sequence-diagram-passenger-refund*** ::: ```mermaid sequenceDiagram participant FE as Frontend participant BE as Backend participant SCSC as Nigeria Service Contract participant TMSC as Ticket Master Contract participant ETSC as ERC20 token Contract FE->>TMSC: request approve(Nigeria Service Contract address, NFTicket_id) TMSC-->>FE: return success BE->>SCSC: refundTicket(NFTicket_id, refund_credit_amount, passenger_wallet_address) SCSC->>SCSC: verify NFTicket credit balance >= refund_credit_amount SCSC->>SCSC: verifyIsGetApproved(Nigeria Service Contract address, NFTicket_id) SCSC->>TMSC: request transferFrom(passenger wallet address, Ticket Master contract addrress, NFTicket_id) SCSC->>SCSC: deductCredit(NFTicket_id, refund_credit_amount) SCSC->>SCSC: get Price per credit and ERC20 token address SCSC->>TMSC: request transferERC20TokenToWallet(msg.sender[Backend_wallet_address], ERC20 token address, refund_credit_amount * price per credit) TMSC->>TMSC: verify caller is inServiceContractWhitelist TMSC->>ETSC: transfer(msg.sender[Backend_wallet_address], refund_credit_amount * price per credit) SCSC->>TMSC: request transferNFTicketToOriginalOwner(passenger wallet address, NFTicket_id) TMSC->>TMSC: verify caller is inServiceContractWhitelist TMSC->>TMSC: _transfer(Ticket Master contract addrress, passenger wallet addres, NFTicket_id) SCSC->>SCSC: verifyTicketOwner(passenger wallet address, NFTicket_id) SCSC-->>BE: return refund_credit_amount * price per credit ``` Backend will then exchange ERC20 token (to other crypto or cash) and transfer refund to passenger ### passenger complain 待規劃 ###### tags: `NFTicket`