Guest User

Untitled

a guest
Jan 22nd, 2018
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.22 KB | None | 0 0
  1. pragma solidity ^0.4.19;
  2.  
  3. contract GometBridge {
  4.  
  5. event LogTransactionCreated(bytes32 hash, uint nonce, bytes data);
  6. event LogTransactionApproved(bytes32 hash, uint nonce, bytes data);
  7. event LogTransactionDiscarded(bytes32 hash);
  8. event LogTransactionRevoked(bytes32 hash);
  9. event LogTransactionExecuted(bytes32 hash, uint nonce, bytes data, bytes32[] sigs);
  10.  
  11. function GometBridge(address[] _signers) public {
  12. require(checkSignersOrder(_signers));
  13.  
  14. signers.length = _signers.length;
  15. for (uint i=0;i<_signers.length;i++) {
  16. signers[i] = _signers[i];
  17. }
  18. }
  19.  
  20. function checkSignersOrder(address[] _signers) internal pure returns (bool) {
  21. for (uint i=0;i<_signers.length;i++) {
  22. if (i>0 && uint(_signers[i-1])<uint(_signers[i])) {
  23. return false;
  24. }
  25. }
  26. }
  27.  
  28. address[] public signers;
  29.  
  30. struct Signature {
  31. bool exists;
  32. uint8 v;
  33. bytes32 r;
  34. bytes32 s;
  35. }
  36.  
  37. struct Transaction {
  38. bool exists;
  39. bool executed;
  40. uint blockstart;
  41. uint nonce;
  42. bytes data;
  43. uint count;
  44. mapping (address=>Signature) sigs;
  45. }
  46.  
  47. mapping (bytes32 => Transaction) public trns;
  48.  
  49. function verifySignature(bytes32 _hash, bytes32[] _sigs) view public
  50. returns (bool) {
  51.  
  52. uint signerNo=0;
  53.  
  54. for (uint i=0;i<_sigs.length;i+=3) {
  55.  
  56. // retrieve the signer
  57.  
  58. uint8 v = uint8(_sigs[i][0]);
  59. bytes32 r = _sigs[i+1];
  60. bytes32 s = _sigs[i+2];
  61. address signer = ecrecover(_hash,v,r,s);
  62.  
  63. // check that this signer exists in the current signer list
  64.  
  65. while (signerNo<signers.length && signers[signerNo]!=signer) {
  66. signerNo++;
  67. }
  68. if (signerNo>=signers.length) {
  69. return false;
  70. }
  71.  
  72. // jump to the next signer, to avoid duplicates
  73.  
  74. signerNo++;
  75.  
  76. }
  77. return true;
  78. }
  79.  
  80. function isSigner( address _addr) public view returns (bool) {
  81.  
  82. for (uint i=0;i<signers.length;i++) {
  83. if (signers[i]==_addr) {
  84. return true;
  85. }
  86. }
  87. return false;
  88. }
  89.  
  90.  
  91. function approveTransactionHash(uint _nonce, bytes _data) public view returns (bytes32) {
  92. return keccak256("approveTransaction:",keccak256(_nonce,_data));
  93. }
  94.  
  95. function revokeTransactionHash(bytes32 _hash) public view returns (bytes32) {
  96. return keccak256("approveTransaction:",_hash);
  97. }
  98.  
  99. function createTransaction(uint _nonce, bytes _data, uint8 _v, bytes32 _r, bytes32 _s) public {
  100. require(isSigner(msg.sender));
  101.  
  102. bytes32 hash = keccak256(_nonce,_data);
  103.  
  104. trns[hash].exists = true;
  105. trns[hash].nonce = _nonce;
  106. trns[hash].executed = false;
  107. trns[hash].data = _data;
  108. trns[hash].blockstart = block.number + 50;
  109.  
  110. LogTransactionCreated(hash, _nonce, _data);
  111.  
  112. approveTransaction(hash,_v,_r,_s);
  113. }
  114.  
  115. /// approve a request
  116. function approveTransaction(bytes32 _hash, uint8 _v, bytes32 _r, bytes32 _s) public {
  117.  
  118. address signer = ecrecover(keccak256("approveTransaction:",_hash),_v,_r,_s);
  119.  
  120. require(isSigner(signer));
  121. require(!trns[_hash].sigs[signer].exists);
  122.  
  123. trns[_hash].sigs[signer].exists = true;
  124. trns[_hash].sigs[signer].v = _v;
  125. trns[_hash].sigs[signer].r = _r;
  126. trns[_hash].sigs[signer].s = _s;
  127. trns[_hash].count++;
  128.  
  129. if ((2 * trns[_hash].count) /3 >= signers.length) {
  130. if (trns[_hash].blockstart >= block.number) {
  131. executeTransaction(_hash);
  132. }
  133. }
  134. }
  135.  
  136. function revokeTransaction(bytes32 _hash, uint8 _v, bytes32 _r, bytes32 _s) public {
  137. address signer = ecrecover(keccak256("revokeTransaction:",_hash),_v,_r,_s);
  138. require(isSigner(signer));
  139.  
  140. delete trns[_hash];
  141. LogTransactionRevoked(_hash);
  142. }
  143.  
  144. event LogDiscardedSignature(bytes32 _hash);
  145.  
  146. function executeTransaction(bytes32 _hash) public {
  147.  
  148. require(trns[_hash].exists);
  149. require(!trns[_hash].executed);
  150. require(trns[_hash].blockstart >= block.number);
  151.  
  152. // -- pack signatures
  153. bytes32[] memory sigs=new bytes32[](3*trns[_hash].count);
  154. uint offset = 0;
  155. for (uint i=0;i<signers.length;i++) {
  156. Signature memory sig = trns[_hash].sigs[signers[i]];
  157. if (sig.v != 0) {
  158. sigs[offset++]=bytes32(sig.v);
  159. sigs[offset++]=sig.r;
  160. sigs[offset++]=sig.s;
  161. }
  162. }
  163.  
  164. // -- at this point check all signatures are processed,
  165. // if in some point a signer is removed, this means that
  166. // this transaction should be discarded
  167.  
  168. if (offset < 3*trns[_hash].count) {
  169. LogTransactionDiscarded(_hash);
  170. delete trns[_hash];
  171. return;
  172. }
  173.  
  174. LogTransactionExecuted(_hash, trns[_hash].nonce, trns[_hash].data, sigs);
  175.  
  176. require(this.call(trns[_hash].data));
  177. trns[_hash].executed = true;
  178.  
  179. }
  180.  
  181. function executeTransaction(uint _nonce, bytes _data, bytes32[] _sigs) public {
  182.  
  183. bytes32 hash = keccak256(_nonce,_data);
  184. require(!trns[hash].exists);
  185.  
  186. trns[hash].exists = true;
  187. require(verifySignature(hash,_sigs));
  188.  
  189. require(this.call(_data));
  190.  
  191. }
  192. function internalChangeSigners( address[] _signers) public {
  193.  
  194. require(msg.sender == address(this));
  195. require(checkSignersOrder(_signers));
  196.  
  197. signers.length = _signers.length;
  198. for (uint i=0;i<_signers.length;i++) {
  199. signers[i] = _signers[i];
  200. }
  201.  
  202. }
  203.  
  204.  
  205. }
  206.  
  207. contract GometParent is GometBridge {
  208.  
  209. event LogLockToChild(address from, uint value);
  210. event LogUnlockFromChild(address to, uint value);
  211.  
  212. function GometParent(address[] _signers)
  213. GometBridge(_signers) public
  214. {
  215. }
  216.  
  217. function lockToChild() public {
  218. LogLockToChild(msg.sender,msg.value);
  219. }
  220.  
  221. function internalUnlockFromChild(address _to, uint _value) public {
  222. require(msg.sender == address(this));
  223. _to.transfer(_value);
  224. LogUnlockFromChild(_to,_value);
  225. }
  226.  
  227. }
  228.  
  229. contract GometChild is GometBridge {
  230.  
  231. event LogMint(address to, uint amount);
  232. event LogSetFee(uint fee);
  233. event LogUnlockFromChild(address from, uint amount);
  234. event LogMintGas(address to, uint amount);
  235.  
  236. MintableToken public weth;
  237. address public maintainers;
  238. uint public fee;
  239.  
  240. function GometChild(address[] _signers, address _maintainers, uint _fee) public
  241. GometBridge(_signers) {
  242. weth = new MintableToken();
  243. maintainers = _maintainers;
  244. fee = _fee;
  245. }
  246.  
  247. // This is called by nodes when a GometParent.LogLockToChild event is found
  248. function internalLockToChild(address _to, uint _amount) public {
  249. require(msg.sender == address(this));
  250.  
  251. weth.mint(_to,_amount);
  252. LogMint(_to, _amount);
  253. }
  254.  
  255. function internalSetFee(uint _fee) public {
  256. require(msg.sender == address(this));
  257.  
  258. fee = _fee;
  259. LogSetFee(_fee);
  260. }
  261.  
  262. function unlockFromChild() public {
  263. weth.burn(msg.sender,msg.value);
  264.  
  265. // Parent chain will catch this event to unlock
  266. LogUnlockFromChild(msg.sender, msg.value);
  267. }
  268.  
  269. function mintGas(uint _ethAmount) public {
  270.  
  271. require(_ethAmount >= weth.balanceOf(msg.sender));
  272.  
  273. uint wethfee = (_ethAmount * fee) / 10000;
  274. uint wethamout = _ethAmount - wethfee;
  275.  
  276. msg.sender.transfer(wethamout);
  277.  
  278. weth.burn(msg.sender,_ethAmount);
  279. weth.mint(maintainers,wethfee);
  280.  
  281. LogMintGas(msg.sender, wethamout);
  282.  
  283. }
  284.  
  285. }
  286.  
  287.  
  288. contract MintableToken {
  289. address owner;
  290.  
  291. function MintableToken() public {
  292. owner = msg.sender;
  293. }
  294. function mint(address _to, uint _value) public {
  295. assert(owner==msg.sender);
  296. }
  297. function burn(address _of, uint _value) public {
  298. assert(owner==msg.sender);
  299. }
  300. function balanceOf(address _addr) public returns(uint) {
  301. return 0;
  302. }
  303. }
Add Comment
Please, Sign In to add comment