-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpackage_delivery.sol
More file actions
158 lines (137 loc) · 4.09 KB
/
package_delivery.sol
File metadata and controls
158 lines (137 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
pragma solidity ^0.4.23;
contract Process {
enum State {
Initiated, // 0
InProgress, // 1
Ended // 2
}
State public state;
modifier is_in_progress() {
require(state == State.InProgress, "Process is not in progress");
_;
}
constructor() public {
state = State.Initiated;
}
function start() internal {
require(state == State.Initiated, "Process has been already started");
state = State.InProgress;
}
function end() internal is_in_progress() {
state = State.Ended;
}
function get_process_state() public view returns(State) {
return state;
}
}
contract PackageDelivery is Process {
address public sender;
address public carrier;
address public recipient;
uint failed_deliveries;
uint delivered_confirmation_until;
// set to lower timeout for testing
uint delivered_confirmation_timeout = 60; // in seconds
enum PackageDeliveryState {
Preparing, // 0
HandoverToCarrier, // 1
InDelivery, // 2
HandoverToRecipient, // 3
Delivered, // 4
ReturningToSender, // 5
HandoverToSender, // 6
Returned // 7
}
PackageDeliveryState package_state;
modifier allowed_actor(address _actor) {
require(msg.sender == _actor, "Not authorized");
_;
}
modifier package_in_state(PackageDeliveryState _state) {
require(_state == package_state, "Invalid action");
_;
}
constructor(address _carrier, address _recipient) public {
failed_deliveries = 0;
sender = msg.sender;
carrier = _carrier;
recipient = _recipient;
start();
package_state = PackageDeliveryState.Preparing;
}
function get_status() public view returns (PackageDeliveryState) {
return package_state;
}
function hand_over_to_carrier()
public
is_in_progress()
allowed_actor(sender)
package_in_state(PackageDeliveryState.Preparing)
{
package_state = PackageDeliveryState.HandoverToCarrier;
}
function accept_package_for_delivery()
public
is_in_progress()
allowed_actor(carrier)
package_in_state(PackageDeliveryState.HandoverToCarrier)
{
package_state = PackageDeliveryState.InDelivery;
}
function hand_over_to_recipient()
public
is_in_progress()
allowed_actor(carrier)
package_in_state(PackageDeliveryState.InDelivery)
{
package_state = PackageDeliveryState.HandoverToRecipient;
delivered_confirmation_until = now + delivered_confirmation_timeout;
}
function accept_package()
public
is_in_progress()
allowed_actor(recipient)
package_in_state(PackageDeliveryState.HandoverToRecipient)
{
require(
now <= delivered_confirmation_until,
"Delivery confirmation timed out."
);
package_state = PackageDeliveryState.Delivered;
end();
}
function unable_to_deliver()
public
is_in_progress()
allowed_actor(carrier)
package_in_state(PackageDeliveryState.HandoverToRecipient)
{
require(
now > delivered_confirmation_until,
"Delivery confirmation didn't time out yet."
);
failed_deliveries++;
if (failed_deliveries >= 3) {
package_state = PackageDeliveryState.ReturningToSender;
} else {
package_state = PackageDeliveryState.InDelivery;
}
}
function return_to_sender()
public
is_in_progress()
allowed_actor(carrier)
package_in_state(PackageDeliveryState.ReturningToSender)
{
package_state = PackageDeliveryState.HandoverToSender;
}
function confirm_pkg_return()
public
is_in_progress()
allowed_actor(sender)
package_in_state(PackageDeliveryState.HandoverToSender)
{
package_state = PackageDeliveryState.Returned;
end();
}
}