-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogistic.sol
213 lines (169 loc) · 7.25 KB
/
logistic.sol
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
pragma solidity ^0.4.24;
contract LogisticEvents {
// sign contract
event onSign
(
address addr, // User address
string name, // User name
uint256 idCard, // User Id Card
uint256 scoreCredit, // Credit score
uint256 userType // User type ,1:customer,2:driver
);
// create order
event onCreateOrder
(
uint256 id, // order id
uint256 eth, // eth custumer pay total
uint256 custumerIdCard, // custumer id card
address custumerAddr, // custumer address
uint256 driverIdCard, // driver id card
address driverAddr // driver address
);
event onConfirmOrder(
uint256 orderId // order id
);
}
contract Logistic1 is LogisticEvents{
// address private admin = msg.sender;
/** contract total money */
uint256 public pool = 0;
/**team 5% when someone win*/
// uint256 public com = 5;
InsuranceInterface constant private Insurance = InsuranceInterface(0x0971b5d216af52c411c9016bbc63665b4e6f2542);
ETCInterface constant private ETC = ETCInterface(0x9876e235a87f520c827317a8987c9e1fde804485);
//****************
// User DATA
//****************
mapping (uint256 => LogisticDatasets.User) public users; // (idCard => users) include customer and driver
//****************
// Order DATA
//****************
mapping (uint256 => LogisticDatasets.Order) public orders; // (orderId => order) orders
//****************
// Fee DATA
//****************
mapping (uint256 => LogisticDatasets.ParticipantFees) public participantFees; // (orderId => ParticipantFees) orders
//****************
// init DATA
//****************
uint256 unitDriverPrice;// unit diver price per km
uint256 unitEtcPrice;// unit etc price per
uint256 insurancePercent;// estimate price
uint256 currentOrderId;// order initial id
// uint256 insuranceFee;// totalFee - etcTotalPrice - driverFee
constructor()
public
{
unitDriverPrice = 10 ** 16;// 0.01eth
insurancePercent = 2; // 2%
unitEtcPrice = 5 * (10 ** 14);// 0.0005eth
currentOrderId = 0;// the order id is 0 when the contract started
}
/**
* if customer and driver are all sign contract
*/
modifier isSign(uint256 _idCard,uint256 _driverIdCard) {
require(users[_idCard].idCard != 0, "sorry customer must be sign the contract");
require(users[_driverIdCard].idCard != 0, "sorry driver must be sign the contract");
_;
}
modifier onlyCustomer(address _customerAddr,uint256 _orderId){
require(orders[_orderId].custumerAddr == _customerAddr,"must be confirm by the customer who owned the order");
_;
}
modifier verifyOrder(uint256 _orderId){
require(orders[_orderId].id > 0,"order must be exist");
require(orders[_orderId].status == 1,"order must be pay status");
_;
}
function put() public payable{
pool=pool + msg.value;
}
/** customer pay total*/
function corePay(uint256 _distance,uint256 _idCard,uint256 _driverIdCard,string _goods,uint256 _estimatePrice)
isSign(_idCard,_driverIdCard)
public payable{
pool = pool + msg.value;
currentOrderId = currentOrderId +1;
address driverAddr = users[_driverIdCard].addr;
orders[currentOrderId] = LogisticDatasets.Order(currentOrderId,msg.value,_idCard,msg.sender,_driverIdCard,driverAddr,_distance,_goods,1);
emit LogisticEvents.onCreateOrder(currentOrderId,msg.value,_idCard,msg.sender,_driverIdCard,driverAddr);
participantFees[currentOrderId] = LogisticDatasets.ParticipantFees(_distance * unitEtcPrice,_distance * unitDriverPrice,_estimatePrice * insurancePercent / 100);
uint256 balance = msg.value - participantFees[currentOrderId].etcFee - participantFees[currentOrderId].driverFee - participantFees[currentOrderId].insuranceFee;
require(balance >= 0,"balance must be greater than 0");
if(balance > 0){
msg.sender.transfer(balance);
}
Insurance.core.value(participantFees[currentOrderId].insuranceFee)(currentOrderId,_idCard,msg.sender,_distance,_goods,_estimatePrice);
ETC.core.value(participantFees[currentOrderId].etcFee)(currentOrderId,msg.sender);
pool = pool - participantFees[currentOrderId].insuranceFee - participantFees[currentOrderId].etcFee;
}
/**unconfirm ,transfer to driver*/
function confirm(uint256 _orderId)
onlyCustomer(msg.sender,_orderId)
verifyOrder(_orderId)
public{
address driverAddr = orders[_orderId].driverAddr;
uint256 driverFee = participantFees[_orderId].driverFee;
driverAddr.transfer(driverFee);
pool = pool - driverFee;
orders[_orderId].status = 2;
emit LogisticEvents.onConfirmOrder(_orderId);
ETC.confirm(_orderId);
users[orders[_orderId].driverIdCard].scoreCredit++;
}
/**unconfirm ,transfer back to customer*/
function unconfirm(uint256 _orderId)
onlyCustomer(msg.sender,_orderId)
verifyOrder(_orderId)
public{
address custumerAddr = orders[_orderId].custumerAddr;
uint256 driverFee = participantFees[_orderId].driverFee;
custumerAddr.transfer(driverFee);
pool = pool - driverFee;
orders[_orderId].status = 3;
emit LogisticEvents.onConfirmOrder(_orderId);
ETC.confirm(_orderId);
users[orders[_orderId].driverIdCard].scoreCredit--;
}
function sign(string name, uint256 idCard,uint256 userType) public{
require(idCard>0,"customer id card must be greater than 0");
users[idCard]=LogisticDatasets.User(msg.sender,name,idCard,100,userType);
emit LogisticEvents.onSign(msg.sender,name,idCard,100,userType);
}
}
interface InsuranceInterface {
function core(uint256 logisticOrderId,uint256 customerIdCard,address customerAddr,uint256 distance,string goods,uint256 estimatePrice) external payable;
}
interface ETCInterface {
function core(uint256 logisticOrderId,address customerAddr) external payable;
function confirm(uint256 logisticOrderId) external;
}
//==============================================================================
// Logistic Datasets
//==============================================================================
library LogisticDatasets {
struct User {
address addr; // User address
string name; // User name
uint256 idCard; // User Id Card
uint256 scoreCredit; // Credit score
uint256 userType; // User type ,1:customer,2:driver
}
struct Order {
uint256 id; // order id
uint256 eth; // eth custumer pay total
uint256 custumerIdCard; // custumer id card
address custumerAddr; // custumer address
uint256 driverIdCard; // driver id card
address driverAddr; // driver address
uint256 distance; // distance
string goods; // goods
uint256 status; //order status,1=>payed;2=>confirmed;3=>unconfirmed
}
struct ParticipantFees{
uint256 etcFee; //etc estimate fee
uint256 driverFee; //driver receive fee
uint256 insuranceFee; //insurance fee
}
}