Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.87 KB | None | 0 0
  1. pragma solidity ^0.5.0;
  2. pragma experimental ABIEncoderV2;
  3.  
  4. import "./RUCToken.sol";
  5. import "./SafeMath.sol";
  6.  
  7. contract RUCMarket {
  8.  
  9. using SafeMath for uint256;
  10.  
  11. address payable admin;
  12. uint256 public tokenPrice;
  13. uint256 public tokensSold;
  14.  
  15. uint requestedProducts;
  16. uint totalOrderNumber = 0;
  17. uint totalProductNumber = 0;
  18. uint totalCourierNumber = 0;
  19.  
  20.  
  21. RUCToken token;
  22.  
  23. enum State {REQUESTED, PAYED, SELLER_COMFIRMED, SELLER_SENT,
  24. BUYER_GOT, COMPLETED, WILL_RETURN, BUYER_SENT, SELLER_GOT, CANCLED}
  25.  
  26. struct Order {
  27. uint id;
  28. uint productId;
  29. uint productValue;
  30. uint deliverFee;
  31. uint number;
  32. address seller;
  33. address buyer;
  34. uint courierId;
  35. State state;
  36. uint deliverTime;
  37. }
  38.  
  39. struct Product {
  40. uint id;
  41. string name;
  42. uint price;
  43. uint number;
  44. uint unconfirmedRequests;
  45. //address[] buyers;
  46. //mapping (address => bool) isConfirmed;
  47. address seller;
  48. //Order[] orders;
  49. }
  50.  
  51.  
  52. struct Courier {
  53. uint id;
  54. address accountAddress;
  55. string companyName;
  56. uint fee;
  57. }
  58.  
  59. mapping (address => bool) registerTable;
  60. mapping (address => bool) isCourier;
  61.  
  62. Product[] products;
  63. Order[] orders;
  64. Courier[] public couriers;
  65.  
  66.  
  67. event Purchase(uint _productId, uint _price, uint _number, address _seller, address _buyer);
  68. event TokenSell(address _buyer, uint256 _amount);
  69.  
  70. constructor(RUCToken _tokenContract, uint256 _tokenPrice) public {
  71. token = _tokenContract;
  72. admin = msg.sender;
  73. tokenPrice = _tokenPrice;
  74. }
  75.  
  76.  
  77. /************************ Token Part **************************************************************/
  78.  
  79. function buyTokens(uint256 _numberOfTokens) public payable {
  80.  
  81. // Require that value is equal to tokens
  82. require(msg.value == _numberOfTokens.mul(tokenPrice));
  83.  
  84. // Require that the contract has enough tokens
  85. require(token.balanceOf(address(this))>= _numberOfTokens);
  86.  
  87. // Require that a transfer is successful
  88. require(token.transfer(msg.sender, _numberOfTokens));
  89.  
  90. // Keep track of tokensSold
  91. tokensSold += _numberOfTokens;
  92.  
  93. // Trigger Sell Event
  94. emit TokenSell(msg.sender, _numberOfTokens);
  95. }
  96.  
  97. function showMyBalance() public view returns(uint){
  98. return token.balanceOf(msg.sender);
  99. }
  100.  
  101. function endSale() public {
  102. require(msg.sender == admin);
  103. require(token.transfer(admin, token.balanceOf(address(this))));
  104.  
  105. // Just transfer the balance to admin
  106. admin.transfer(address(this).balance);
  107. }
  108.  
  109. /************************ Purchase Part **************************************************************/
  110.  
  111.  
  112. function I_am_courier(string memory _companyName, uint _fee) public {
  113. require(!isCourier[msg.sender]); // prevent double register
  114.  
  115. Courier memory _courier;
  116. totalCourierNumber = totalCourierNumber.add(1);
  117. _courier.id = totalCourierNumber; //id = totalCourierNumber
  118. _courier.accountAddress = msg.sender;
  119. _courier.companyName = _companyName;
  120. _courier.fee = _fee;
  121.  
  122. couriers.push(_courier);
  123. isCourier[msg.sender] = true;
  124. }
  125. // how to pass parameter : string?
  126. function addProduct(string memory _name, uint _price, uint _number) public {
  127. require(_price > 0);
  128. require(_number > 0);
  129.  
  130. Product memory _product;
  131. totalProductNumber = totalProductNumber.add(1);
  132. _product.id = totalProductNumber; //id = totalProductNumber
  133. _product.name = _name;
  134. _product.price = _price;
  135. _product.number = _number;
  136. _product.seller = msg.sender;
  137.  
  138. products.push(_product);
  139. }
  140.  
  141.  
  142. function purchaseRequest(uint _productId, uint _requestNumber, uint _courierId) external {
  143. require(_productId != 0);
  144.  
  145. //(Product memory _product, uint _productIndex) = findProductAndIndexById(_productId);
  146. Product memory _product = findProductById(_productId);
  147. require(_productId == _product.id); //_product does exist
  148. //require(_courierId > 0 && _courierId <= couriers.length);
  149. require(_courierId !=0);
  150. require(_requestNumber != 0 && _requestNumber <= _product.number);
  151. require((_product.price.mul(_requestNumber)) <= token.balanceOf(msg.sender));
  152. require(_product.seller != msg.sender); // can not buy things from one himself
  153.  
  154. Order memory _order;
  155. totalOrderNumber = totalOrderNumber.add(1);
  156. _order.id = totalOrderNumber; // order id = totalOrderNumber
  157. _order.productId = _productId;
  158. _order.productValue = _product.price.mul(_requestNumber); // number * price
  159. Courier memory _courier = findCourierById(_courierId);
  160. _order.deliverFee = _courier.fee; //deliver fee
  161. _order.number = _requestNumber;
  162. _order.seller = _product.seller;
  163. _order.buyer = msg.sender;
  164. _order.courierId = _courierId;
  165. _order.state = State.REQUESTED;
  166.  
  167. orders.push(_order);
  168.  
  169. // products[_productIndex].number = products[_productIndex].number.sub(_requestNumber);
  170.  
  171. }
  172.  
  173.  
  174. function buyerPayOrder(uint _orderId) external {
  175. require(_orderId !=0);
  176.  
  177. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  178. require(_order.id != 0); // order exist
  179.  
  180. require(msg.sender == _order.buyer);
  181. require(_order.state == State.REQUESTED);
  182.  
  183. uint totalValue = _order.productValue.add(_order.deliverFee); //totalValue = productValue + deliverFee
  184. token.approve(msg.sender, address(this), totalValue);
  185. require(token.allowance(msg.sender, address(this)) >= totalValue);
  186. token.transferFrom(msg.sender, address(this), totalValue);
  187. orders[_orderIndex].state = State.PAYED;
  188.  
  189. }
  190.  
  191. function sellerComfirmOrder(uint _orderId) external {
  192. require(_orderId != 0);
  193. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  194. require(_order.id != 0); // order exist
  195.  
  196. require(msg.sender == _order.seller );
  197. require(_order.state == State.PAYED); // require preious state
  198. (Product memory _product,uint _productIndex) = findProductAndIndexById(_order.productId);
  199. require(_order.number <= _product.number);
  200.  
  201.  
  202.  
  203. orders[_orderIndex].state = State.SELLER_COMFIRMED; //change state to "..."
  204. products[_productIndex].number = products[_productIndex].number.sub(_order.number); // update product number
  205.  
  206. emit Purchase( _order.productId, _product.price, _order.number, _order.seller, _order.buyer);
  207. }
  208.  
  209. function sellerSendProduct(uint _orderId, bytes32 _hash, bytes calldata _sig) external {
  210. require(_orderId != 0);
  211. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  212. require(_order.id != 0); // order exist
  213. require(msg.sender == _order.seller); //msg.sender == order's seller
  214.  
  215. Courier memory _courier = findCourierById(_order.courierId);
  216. require(recover(_hash,_sig) == _courier.accountAddress); // verify signature from courier
  217.  
  218. require(_order.state == State.SELLER_COMFIRMED); // state == SELLER_COMFIRMED
  219.  
  220. token.transfer(_courier.accountAddress, _order.deliverFee); // pay deliver fee
  221. orders[_orderIndex].state = State.SELLER_SENT; //change state to "SELLER_SENT"
  222. }
  223.  
  224. function OrderDeliveredToBuyer(uint _orderId, bytes32 _hash, bytes calldata _sig) external {
  225. require(_orderId != 0);
  226. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  227. require(_order.id != 0); // order exist
  228.  
  229. require(recover(_hash,_sig) == _order.buyer); // verify signature from buyer
  230.  
  231. Courier memory _courier = findCourierById(_order.courierId);
  232. require(msg.sender == _courier.accountAddress); //msg.sender == order's courier
  233.  
  234. require(_order.state == State.SELLER_SENT); // require previous state
  235.  
  236. //token.transferFrom(address(this), _order.seller, _order.productValue);
  237. orders[_orderIndex].state = State.BUYER_GOT;
  238. orders[_orderIndex].deliverTime = now; // set the deliverTime as 'now'
  239. }
  240.  
  241. function buyerConfirm(uint _orderId) external {
  242. require(_orderId != 0);
  243. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  244. require(_order.id != 0); // order exist
  245.  
  246. require(msg.sender == _order.buyer); // msg.sender == buyer
  247. require(_order.state == State.BUYER_GOT); // require previous state
  248.  
  249. //token.transferFrom(address(this), _order.seller, _order.productValue);
  250. token.transfer(_order.seller, _order.productValue);
  251. orders[_orderIndex].state = State.COMPLETED;
  252. }
  253.  
  254. function sellerGetMoneyFromOrder(uint _orderId) external {
  255. require(_orderId != 0);
  256. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  257. require(_order.id != 0); // order exist
  258.  
  259. require(msg.sender == _order.seller); //msg.sender == seller
  260. require(now > _order.deliverTime.add(1 minutes)); // consideration time is over
  261. require(_order.state == State.BUYER_GOT); // Has't been confirmed
  262.  
  263. //token.transferFrom(address(this), _order.seller, _order.productValue);
  264. token.transfer(_order.seller, _order.productValue);
  265. orders[_orderIndex].state = State.COMPLETED;
  266. }
  267.  
  268. function buyerWillRuturnProduct(uint _orderId) external {
  269. require(_orderId !=0);
  270.  
  271. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  272. require(_order.id != 0); // order exist
  273.  
  274. require(msg.sender == _order.buyer);
  275. require(_order.state == State.BUYER_GOT); // state == BUYER_GOT
  276. require(now <= _order.deliverTime.add(1 minutes)); // within the consideration time limit
  277.  
  278. token.approve(msg.sender, address(this), _order.deliverFee);
  279. require(token.allowance(msg.sender, address(this)) >= _order.deliverFee);
  280. token.transferFrom(msg.sender, address(this), _order.deliverFee);
  281. orders[_orderIndex].state = State.WILL_RETURN;
  282.  
  283. }
  284.  
  285. function buyerSendProduct(uint _orderId, bytes32 _hash, bytes calldata _sig) external {
  286. require(_orderId != 0);
  287. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  288. require(_order.id != 0); // order exist
  289. require(msg.sender == _order.buyer); //msg.sender == order's buyer
  290.  
  291. Courier memory _courier = findCourierById(_order.courierId);
  292. require(recover(_hash,_sig) == _courier.accountAddress); // verify signature
  293.  
  294. require(_order.state == State.WILL_RETURN); // state == WILL_RETURN
  295.  
  296. token.transfer(_courier.accountAddress, _order.deliverFee); // pay deliver fee
  297. orders[_orderIndex].state = State.BUYER_SENT; //change state to "SELLER_SENT"
  298. }
  299.  
  300. function OrderDeliveredToSeller(uint _orderId, bytes32 _hash, bytes calldata _sig) external {
  301. require(_orderId != 0);
  302. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  303. require(_order.id != 0); // order exist
  304.  
  305. require(recover(_hash,_sig) == _order.seller); // verify signature from seller
  306.  
  307. Courier memory _courier = findCourierById(_order.courierId);
  308. require(msg.sender == _courier.accountAddress); //msg.sender == order's courier
  309.  
  310. require(_order.state == State.BUYER_SENT); // require previous state
  311.  
  312. //token.transferFrom(address(this), _order.seller, _order.productValue);
  313. orders[_orderIndex].state = State.SELLER_GOT;
  314. //orders[_orderIndex].deliverTime = now; // reset the deliverTime as 'now'
  315.  
  316. //add product number
  317. uint _productIndex = findProductIndexById(_order.productId);
  318. products[_productIndex].number = products[_productIndex].number.add(_order.number);
  319.  
  320. token.transfer(_order.buyer, _order.productValue); // return the money back to buyer
  321. }
  322.  
  323. function cancleByBuyer(uint _orderId) external {
  324. require(_orderId != 0);
  325. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  326. require(_order.id != 0); // order exist
  327.  
  328. require(msg.sender == _order.buyer); // only buyer call this cancle
  329.  
  330. /*two cases:
  331. 1. before seller send products: buyer can get all the money (token) back
  332. 2. after buyer got the products, before he sends
  333. (which is state WILL_RETURN): similer to buyerConfirm()*/
  334. if(_order.state < State.SELLER_SENT) { // 1. before seller sent
  335. orders[_orderIndex].state = State.CANCLED; // set state as CANCLED
  336. token.transfer(msg.sender, _order.productValue.add(_order.deliverFee)); // transfer token back
  337. }
  338. else if(_order.state == State.WILL_RETURN){
  339. token.transfer(_order.seller, _order.productValue);
  340. orders[_orderIndex].state = State.COMPLETED;
  341. }
  342. }
  343.  
  344. function cancleByCourier(uint _orderId) external {
  345. /* Situation:
  346. courier help qulify the product, and the returning products don't match the requirement.
  347. */
  348.  
  349. require(_orderId != 0);
  350. (Order memory _order,uint _orderIndex) = findOrderAndIndexById(_orderId);
  351. require(_order.id != 0); // order exist
  352.  
  353. Courier memory _courier = findCourierById(_order.courierId);
  354. require(msg.sender == _courier.accountAddress); // only courier call this cancle
  355. require(_order.state == State.WILL_RETURN);
  356.  
  357. token.transfer(_order.seller, _order.productValue.add(_order.deliverFee));
  358. orders[_orderIndex].state = State.COMPLETED;
  359. }
  360. /****************************** Find and Get methods***********************************/
  361. /*
  362. function getProductName(uint _productId) external view returns(string memory) {
  363. Product memory _product = findProductById(_productId);
  364. return _product.name;
  365. }
  366.  
  367. function getProductPrice(uint _productId) external view returns(uint) {
  368. Product memory _product = findProductById(_productId);
  369. return _product.price;
  370. }
  371.  
  372. function getProductNumber(uint _productId) external view returns(uint) {
  373. Product memory _product = findProductById(_productId);
  374. return _product.number;
  375. }
  376.  
  377. function getProductSeller(uint _productId) external view returns(address) {
  378. Product memory _product = findProductById(_productId);
  379. return _product.seller;
  380. }*/
  381.  
  382. function findOrderAndIndexById(uint _orderId) internal view returns(Order memory, uint) {
  383. for(uint i = 0; i < orders.length; i++) {
  384. if(orders[i].id == _orderId){
  385. return (orders[i], i);
  386. }
  387. }
  388.  
  389. Order memory order;
  390.  
  391. return (order, 0);
  392. }
  393.  
  394. function findOrderById(uint _orderid) public view returns(Order memory){
  395. for(uint i = 0; i < orders.length; i++){
  396. if(orders[i].id == _orderid)
  397. return orders[i];
  398. }
  399.  
  400. Order memory order;
  401. return order;
  402. }
  403.  
  404. function findOrdersBySeller(address _seller) external view returns(Order[] memory) {
  405. uint count = 0;
  406. uint i;
  407. uint j = 0;
  408. for(i = 0; i < orders.length; i++){
  409. if(orders[i].seller == _seller){
  410. count ++;
  411. }
  412. }
  413.  
  414. Order[] memory results = new Order[](count);
  415.  
  416. for(i = 0; i < orders.length; i++){
  417. if(orders[i].seller == _seller){
  418. results[j++] = orders[i];
  419. }
  420. }
  421.  
  422. return results;
  423. }
  424.  
  425. function findOrdersByBuyer(address _buyer) external view returns(Order[] memory) {
  426. uint count = 0;
  427. uint i;
  428. uint j = 0;
  429. for(i = 0; i < orders.length; i++){
  430. if(orders[i].buyer == _buyer){
  431. count ++;
  432. }
  433. }
  434.  
  435. Order[] memory results = new Order[](count);
  436.  
  437. for(i = 0; i < orders.length; i++){
  438. if(orders[i].buyer == _buyer){
  439. results[j++] = orders[i];
  440. }
  441. }
  442. return results;
  443. }
  444.  
  445. function findOrdersBycourierId(uint _courierId) external view returns(Order[] memory) {
  446. uint count = 0;
  447. uint i;
  448. uint j = 0;
  449. for(i = 0; i < orders.length; i++){
  450. if(orders[i].courierId == _courierId){
  451. count ++;
  452. }
  453. }
  454.  
  455. Order[] memory results = new Order[](count);
  456.  
  457. for(i = 0; i < orders.length; i++){
  458. if(orders[i].courierId == _courierId){
  459. results[j++] = orders[i];
  460. }
  461. }
  462.  
  463. return results;
  464. }
  465.  
  466.  
  467.  
  468. function findProductAndIndexById(uint _productId) internal view returns(Product memory, uint) {
  469. for(uint i = 0; i < products.length; i++) {
  470. if(products[i].id == _productId){
  471. return (products[i], i);
  472. }
  473. }
  474.  
  475. Product memory product;
  476.  
  477. return (product, 0);
  478. }
  479.  
  480. function findProductIndexById(uint _productId) internal view returns(uint) {
  481. for(uint i = 0; i < products.length; i++) {
  482. if(products[i].id == _productId){
  483. return i;
  484. }
  485. }
  486.  
  487. return 0;
  488. }
  489.  
  490. function findProductById(uint _productId) public view returns(Product memory) {
  491. for(uint i = 0; i < products.length; i++) {
  492. if(products[i].id == _productId){
  493. return products[i];
  494. }
  495. }
  496.  
  497. Product memory product;
  498.  
  499. return product;
  500. }
  501.  
  502. function findCourierById(uint _courierId) public view returns(Courier memory) {
  503. for(uint i = 0; i < couriers.length; i++) {
  504. if(couriers[i].id == _courierId){
  505. return couriers[i];
  506. }
  507. }
  508.  
  509. Courier memory courier;
  510.  
  511. return courier;
  512. }
  513. /*********************************Verify Signature*****************************************/
  514. function recover(bytes32 hash, bytes memory signature)
  515. public
  516. pure
  517. returns (address)
  518. {
  519. bytes32 r;
  520. bytes32 s;
  521. uint8 v;
  522.  
  523. // Check the signature length
  524. if (signature.length != 65) {
  525. return (address(0));
  526. }
  527.  
  528. // Divide the signature in r, s and v variables
  529. // ecrecover takes the signature parameters, and the only way to get them
  530. // currently is to use assembly.
  531. // solium-disable-next-line security/no-inline-assembly
  532. assembly {
  533. r := mload(add(signature, 0x20))
  534. s := mload(add(signature, 0x40))
  535. v := byte(0, mload(add(signature, 0x60)))
  536. }
  537.  
  538. // Version of signature should be 27 or 28, but 0 and 1 are also possible versions
  539. if (v < 27) {
  540. v += 27;
  541. }
  542.  
  543. // If the version is correct return the signer address
  544. if (v != 27 && v != 28) {
  545. return (address(0));
  546. } else {
  547. // solium-disable-next-line arg-overflow
  548. return ecrecover(hash, v, r, s);
  549. }
  550. }
  551. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement