Created
October 13, 2021 14:18
-
-
Save HarukaH001/d639fa09b12505e81d25ae781bc6f6a3 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.6.12+commit.27d51765.js&optimize=false&runs=200&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity ^0.6.12; | |
pragma experimental ABIEncoderV2; | |
import "./SafeMath.sol"; | |
import "./ownable.sol"; | |
enum StateType { Idle, Created, InTransit, Complete, Cancel, Done } | |
struct Deal { | |
bytes32 dealId; | |
address transporter; | |
address customer; | |
string productName; | |
uint minTemperature; | |
uint maxTemperature; | |
uint price; | |
uint quantity; | |
bool cancelable; | |
StateType transportState; | |
} | |
interface FishMarketInterface { | |
struct Stock { | |
bytes32 productId; | |
string productName; | |
uint priceInEther; | |
uint minTemperature; | |
uint maxTemperature; | |
uint quantity; | |
} | |
function getStock(string memory _productName) external view returns(Stock memory stock); | |
function addStockQuantity(uint _quantity, string memory _productName) external; | |
function removeStockQuantity(uint _quantity, string memory _productName) external; | |
} | |
contract Logistic is Ownable{ | |
using SafeMath for uint256; | |
mapping(bytes32 => Deal) public deals; | |
address marketAddress; | |
modifier onlyTransporter(bytes32 dealId) { | |
require(msg.sender == deals[dealId].transporter, "unauthorized"); | |
_; | |
} | |
modifier onlyCustomer(bytes32 dealId) { | |
require(msg.sender == deals[dealId].customer, "unauthorized"); | |
_; | |
} | |
constructor() public { | |
} | |
/* | |
Function to initalize a initDeal | |
@param : customer's address, price (in Ether), minimum and maximum temperature allow, productName | |
*/ | |
function initDeal( | |
address payable _customer, | |
uint _quantity, | |
string memory _productName | |
) public onlyOwner returns(Deal memory) { | |
bytes32 dealId = keccak256(abi.encodePacked( | |
_customer, | |
block.timestamp | |
)); | |
Deal storage deal = deals[dealId]; | |
FishMarketInterface.Stock memory stock = FishMarketInterface(marketAddress).getStock(_productName); | |
require(stock.quantity >= _quantity); | |
deal.dealId = dealId; | |
deal.customer = _customer; | |
deal.minTemperature = stock.minTemperature; | |
deal.maxTemperature = stock.maxTemperature; | |
deal.price = stock.priceInEther * _quantity * 1 ether; | |
deal.quantity = _quantity; | |
deal.productName = _productName; | |
deal.cancelable = false; | |
deal.transportState = StateType.Created; | |
FishMarketInterface(marketAddress).removeStockQuantity(_quantity, _productName); | |
return deal; | |
} | |
function setMarketAddress(address _address) public onlyOwner { | |
marketAddress = _address; | |
} | |
/* | |
Function to transport to customer | |
@param : transporter's address | |
*/ | |
function transport(bytes32 dealId, address _transporter) public onlyOwner { | |
Deal storage deal = deals[dealId]; | |
require(deal.transportState == StateType.Created, "invalid transportState"); | |
deal.transporter = payable(_transporter); | |
deal.transportState = StateType.InTransit; | |
} | |
/* | |
Function to update sensor from transporter | |
@param : current temp | |
*/ | |
function updateTemp(bytes32 dealId, uint _temp) public onlyTransporter(dealId) { | |
Deal storage deal = deals[dealId]; | |
require(deal.transportState == StateType.InTransit, "invalid transportState"); | |
if(_temp > deal.maxTemperature || _temp < deal.minTemperature){ | |
deal.cancelable = true; | |
} | |
} | |
/* | |
Function to cancel current deal if measured temperature is out of range | |
@param: - | |
*/ | |
function cancelDeal(bytes32 dealId) public onlyCustomer(dealId) { | |
Deal storage deal = deals[dealId]; | |
require(deal.transportState == StateType.InTransit, "invalid transportState"); | |
require(deal.cancelable == true, "unmatched cancel condition"); | |
deal.transportState = StateType.Cancel; | |
} | |
/* | |
Function to complete and pay for deal | |
@param : - | |
This function require ether to be transfered. | |
*/ | |
function pay(bytes32 dealId) public onlyCustomer(dealId) payable{ | |
Deal storage deal = deals[dealId]; | |
require(deal.transportState == StateType.InTransit, "invalid transportState"); | |
require(msg.value == deal.price); | |
deal.transportState = StateType.Complete; | |
} | |
/* | |
Function for owner to get ether from contract | |
@param : - | |
*/ | |
function clearance(bytes32 dealId) public onlyOwner payable{ | |
Deal storage deal = deals[dealId]; | |
require(deal.transportState == StateType.Complete || deal.transportState == StateType.Cancel, "invalid transportState"); | |
uint price = deal.price; | |
if (deal.transportState == StateType.Complete){ | |
payable(getOwner()).transfer(price.mul(9).div(10)); | |
payable(deal.transporter).transfer(price.div(10)); | |
} | |
deal.transportState = StateType.Done; | |
} | |
receive() external payable { | |
revert("Not support sending Ethers to this contract directly."); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment