Guest User

Untitled

a guest
Sep 24th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.12 KB | None | 0 0
  1. pragma solidity ^0.4.25;
  2.  
  3. contract Bridge {
  4.  
  5. // message sent to other chains
  6. // srcChain is implicit (this chain), destChain is map key
  7. struct SendMsg {
  8. address srcAddr;
  9. address destAddr;
  10. uint256 value;
  11. // final response status from other chains, -1 unknown, 1 success, 0 fail
  12. int8 status;
  13. }
  14.  
  15. // message received from other chains
  16. // srcChain is map key, destChain is implicit (this chain)
  17. struct RecvMsg {
  18. address srcAddr;
  19. address destAddr;
  20. uint256 value;
  21. bool success; // result of the message
  22. }
  23.  
  24. // msgs sent to other chains, key is destChain
  25. mapping (uint256 => SendMsg[]) public sendMsgsByDestChain;
  26. mapping (uint256 => uint256) public lastSentMsgIdByDestChain;
  27. mapping (uint256 => uint256) public lastAckedMsgIdByDestChain;
  28.  
  29. // received messages from other chains, by srcChain
  30. mapping (uint256 => RecvMsg[]) public recvMsgsBySrcChain;
  31. mapping (uint256 => uint256) public lastMsgIdBySrcChain;
  32.  
  33. // request event, contains only ID information to save storage
  34. event Request(uint256 destChain, uint256 id);
  35. event Response(uint256 srcChain, uint256 id, bool success);
  36.  
  37. address owner;
  38.  
  39. constructor(address _owner) public {
  40. owner = _owner;
  41. }
  42.  
  43. // send message to destChain/destAddr from srcAddr
  44. // srcAddr could be different from msg.sender, if different, usually called by
  45. // other contract to delegate their user
  46. // called by normal user or other contract in the same chain
  47. function send(address srcAddr, uint256 destChain, address destAddr) public payable {
  48. require(srcAddr != address(0) && destChain>0 && destAddr!=address(0));
  49. require(srcAddr.balance >= msg.value, "no enough money");
  50. sendMsgsByDestChain[destChain].push(SendMsg({srcAddr: srcAddr,
  51. destAddr: destAddr, value: msg.value, status: -1}));
  52. uint256 lastMsgId = lastSentMsgIdByDestChain[destChain];
  53. lastSentMsgIdByDestChain[destChain] = lastMsgId + 1; // first message id is 1
  54. emit Request(destChain, lastMsgId + 1);
  55. }
  56.  
  57. // ack request message to destChain/id, result is success
  58. // ack id must be expected
  59. // called by relay server
  60. function ack(uint256 destChain, uint256 id, bool success) public {
  61. require(msg.sender == owner, "only owner is allowed to call ack");
  62. require(destChain>0);
  63. uint256 expectedId = lastAckedMsgIdByDestChain[destChain] + 1;
  64. require(id == expectedId, "id is not expected");
  65. int8 status = success ? int8(1) : int8(0);
  66. sendMsgsByDestChain[destChain][id-1].status = status;
  67. lastAckedMsgIdByDestChain[destChain] = id;
  68. //TOOD: add general message handler
  69. if(!success){
  70. // TODO: if failed, rollback value transer
  71. }
  72. }
  73.  
  74. // forward message from relay server to dest chain
  75. // called by relay server
  76. function forward(uint256 srcChain, uint256 id, address srcAddr, address destAddr) public payable {
  77. require(msg.sender == owner, "only owner is allowed to relay message");
  78. // ensure id is expected, prevent duplicate message and double spent
  79. uint256 expectedMsgId = lastMsgIdBySrcChain[srcChain] + 1;
  80. require(id == expectedMsgId, "id is not expected");
  81.  
  82. bool success = true;
  83. //TODO: add general message handler
  84. if(msg.value>0){
  85. //TODO: limit the gas value to prevent reentry attack
  86. success = destAddr.send(msg.value);
  87. }
  88. lastMsgIdBySrcChain[srcChain] = id;
  89. recvMsgsBySrcChain[srcChain].push(RecvMsg({srcAddr: srcAddr,
  90. destAddr: destAddr, value: msg.value, success: success}));
  91.  
  92. emit Response(srcChain, id, success);
  93. }
  94.  
  95. // called by relay server to withdraw money from contract to himself
  96. function withdraw(uint256 value) public {
  97. require(value>0);
  98. require(msg.sender == owner, "only owner is allowed to withdraw");
  99. require(address(this).balance>=value, "no enough money");
  100.  
  101. owner.transfer(address(this).balance);
  102. }
  103. }
Add Comment
Please, Sign In to add comment