// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.3;
contract DocDelivery{
enum State { undefined, accepted, delivered }
struct data{
uint256 td;
address addrA;
address addrB;
State status;
}
mapping(bytes32 => data) private docDelivery;
modifier onlySender (bytes32 _id) {
require(docDelivery[_id].addrA == msg.sender);
_;
}
modifier validStatus(bytes32 _id, State _status) {
require(docDelivery[_id].status == _status, "Wrong status");
_;
}
modifier deadline(uint t) {
require(block.timestamp < t, "Timer expired");
_;
}
function validID(bytes32 _id, address _addrA, address _addrB, address _addrSC, bytes32 _h, uint256 _tm, uint256 _td)
private pure returns(bool){
return (_id == keccak256(abi.encodePacked( _addrA, _addrB, _addrSC, _h, _tm, _td)));
}
event Result(address indexed account, bytes32 identifier, uint info, bytes evidence);
function getStatus(bytes32 _id) public view returns(State){
return docDelivery[_id].status;
}
function accept(bytes32 _id, address _addrA, bytes32 _h, uint256 _tm, uint256 _td, bytes memory _fc)
validStatus(_id, State.undefined) deadline(_td)
public {
require(validID(_id, _addrA, msg.sender, address(this), _h, _tm, _td), "Invalid identifier");
docDelivery[_id].addrA = _addrA;
docDelivery[_id].addrB = msg.sender;
docDelivery[_id].td = _td;
docDelivery[_id].status = State.accepted;
emit Result(msg.sender, _id, uint(State.accepted),_fc);
}
function publish(bytes32 _id, bytes memory _k)
onlySender(_id) validStatus(_id, State.accepted) deadline(docDelivery[_id].td)
public {
docDelivery[_id].status = State.delivered;
emit Result(msg.sender, _id, uint(State.delivered), _k);
}
}