Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save HarukaH001/d639fa09b12505e81d25ae781bc6f6a3 to your computer and use it in GitHub Desktop.
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=
// 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