-
-
Save Doctordrayfocus/8177bd086097ace3c5c6429bba0182d5 to your computer and use it in GitHub Desktop.
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: GPL-3.0 | |
pragma solidity >=0.4.16 <0.9.0; | |
contract Logistics { | |
// The address of the account that launched the smart contract | |
address initiator; | |
// state data for each member registered on the contract | |
struct memberState { | |
uint balance; | |
uint reputation; | |
} | |
// state data for each delivery transactions executed through the smart contract | |
struct deliveryState { | |
uint deliveryFee; | |
uint status; | |
uint hashedDeliveryDetails; | |
address owner; | |
address assistingMember; | |
uint index; | |
} | |
// An array to store current available deliveries | |
uint[] availableDeliveries; | |
// mapping are live arrays with key and value pairs | |
mapping (address => memberState) public membersData; | |
mapping (address => uint) members; | |
mapping (uint => deliveryState) public deliveryData; | |
// modifiers | |
modifier onlyMember{ | |
require(members[msg.sender] == 1); | |
_; | |
} | |
// errors | |
error notAuthorized(string reason); | |
error insufficientFee(string reason, uint registrationFee); | |
constructor() payable { | |
initiator = msg.sender; | |
// here we will register the initiator of the contract as a member | |
members[msg.sender] = 1; | |
membersData[msg.sender].balance = msg.value; | |
membersData[msg.sender].reputation = 10; | |
} | |
// This is a public function to the current available deliveries | |
function getAvailableDeliveries() public view returns( uint[] memory) { | |
return availableDeliveries; | |
} | |
// A private function remove delivery from current available deliveries | |
function removeFromAvailableDeliveries(uint index) private { | |
if (index >= availableDeliveries.length) return; | |
for (uint i = index; i < availableDeliveries.length-1; i++){ | |
availableDeliveries[i] = availableDeliveries[i+1]; | |
} | |
delete availableDeliveries[availableDeliveries.length-1]; | |
} | |
// A private function add delivery from current available deliveries | |
function addToAvailableDelivery(uint hashedDeliveryDetails) private { | |
deliveryData[hashedDeliveryDetails].index = availableDeliveries.length; | |
availableDeliveries.push(hashedDeliveryDetails); | |
} | |
function register() public payable { | |
uint registrationFee = msg.value; | |
address newMember = msg.sender; | |
if (registrationFee < 10) | |
revert insufficientFee({ | |
reason: "Ether value is less that the required registration fee", | |
registrationFee: 10 | |
}); | |
members[newMember] = 1; | |
membersData[newMember].balance = msg.value; | |
membersData[newMember].reputation = 10; | |
} | |
function requestForDelivery(uint hashedDeliveryDetails) onlyMember public payable { | |
if(members[msg.sender] != 1) | |
revert notAuthorized({ | |
reason: "Only members of this contract can request for delivery" | |
}); | |
uint senderReputation = membersData[msg.sender].reputation; | |
if(senderReputation < 6) | |
revert notAuthorized({ | |
reason: "You have a low reputation, complete more deliveries to increase your reputations" | |
}); | |
deliveryData[hashedDeliveryDetails].deliveryFee = msg.value; | |
deliveryData[hashedDeliveryDetails].status = 0; | |
deliveryData[hashedDeliveryDetails].hashedDeliveryDetails = hashedDeliveryDetails; | |
deliveryData[hashedDeliveryDetails].owner = msg.sender; | |
addToAvailableDelivery(hashedDeliveryDetails); | |
membersData[msg.sender].balance = membersData[msg.sender].balance + msg.value; | |
} | |
function respondToDeliveryRequest(uint hashedDeliveryDetails) onlyMember public { | |
if(members[msg.sender] != 1) | |
revert notAuthorized({ | |
reason: "Only members of this contract can respond to delivery request" | |
}); | |
uint memberReputation = membersData[msg.sender].reputation; | |
if(memberReputation < 1) | |
revert notAuthorized({ | |
reason: "You have exhausted your reputations" | |
}); | |
uint deliveryStatus = deliveryData[hashedDeliveryDetails].status; | |
if(deliveryStatus != 0) | |
revert notAuthorized({ | |
reason: "This delivery is no longer available" | |
}); | |
deliveryData[hashedDeliveryDetails].status = 1; | |
deliveryData[hashedDeliveryDetails].assistingMember = msg.sender; | |
removeFromAvailableDeliveries(deliveryData[hashedDeliveryDetails].index); | |
} | |
function markDeliveryAsCompleted(uint hashedDeliveryDetails) onlyMember public { | |
if(members[msg.sender] != 1) { | |
revert notAuthorized({ | |
reason: "Only members of this contract can update this delivery" | |
}); | |
} | |
address assistingMember = deliveryData[hashedDeliveryDetails].assistingMember; | |
if(assistingMember != msg.sender) { | |
revert notAuthorized({ | |
reason: "You don't have access to update this delivery" | |
}); | |
} | |
deliveryData[hashedDeliveryDetails].status = 2; | |
} | |
function markDeliveryAsCancled(uint hashedDeliveryDetails) onlyMember public { | |
if(members[msg.sender] != 1) { | |
revert notAuthorized({ | |
reason: "Only members of this contract can update this delivery" | |
}); | |
} | |
address assistingMember = deliveryData[hashedDeliveryDetails].assistingMember; | |
if(assistingMember != msg.sender && msg.sender != initiator) { | |
revert notAuthorized({ | |
reason: "You don't have access to update this delivery" | |
}); | |
} | |
deliveryData[hashedDeliveryDetails].status = 0; | |
addToAvailableDelivery(hashedDeliveryDetails); | |
if (assistingMember == msg.sender) { | |
membersData[msg.sender].reputation = membersData[msg.sender].reputation - 5; | |
} | |
if (msg.sender == initiator) { | |
membersData[msg.sender].reputation = membersData[msg.sender].reputation - 6; | |
} | |
} | |
function markDeliveryAsConfirmed(uint hashedDeliveryDetails) onlyMember public { | |
if(members[msg.sender] != 1) { | |
revert notAuthorized({ | |
reason: "Only members of this contract can update this delivery" | |
}); | |
} | |
address deliveryOwner = deliveryData[hashedDeliveryDetails].owner; | |
if(deliveryOwner != msg.sender && msg.sender != initiator) { | |
revert notAuthorized({ | |
reason: "You don't have access to confirm this delivery" | |
}); | |
} | |
deliveryData[hashedDeliveryDetails].status = 3; | |
address assistingMember = deliveryData[hashedDeliveryDetails].assistingMember; | |
uint deliveryFee = deliveryData[hashedDeliveryDetails].deliveryFee; | |
membersData[deliveryOwner].balance = membersData[deliveryOwner].balance - deliveryFee; | |
membersData[assistingMember].reputation = membersData[assistingMember].reputation + 3; | |
membersData[assistingMember].balance = membersData[assistingMember].balance + deliveryFee; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment