Guest User

Untitled

a guest
Nov 23rd, 2017
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.92 KB | None | 0 0
  1. pragma solidity ^0.4.11;
  2.  
  3.  
  4. /**
  5. * @title MultiSigMowjowMultiSigMowjow Allows multiple parties to agree on transactions before execution.
  6. */
  7. contract MultiSigMowjow {
  8.  
  9. event Confirmation(address indexed sender, uint indexed transactionId);
  10. event Submission(uint indexed transactionId);
  11. event Execution(uint indexed transactionId);
  12. event ExecutionFailure(uint indexed transactionId);
  13. event Deposit(address indexed sender, uint value);
  14. event OwnerAddition(address indexed owner);
  15. event OwnerRemoval(address indexed owner);
  16. event RequirementChange(uint required);
  17.  
  18. mapping (address => bool) isOwner;
  19. address[] public owners;
  20. mapping (uint => TransactionMultisig) public transactions;
  21. mapping (uint => mapping (address => bool)) public confirmations;
  22. uint public transactionCount;
  23. uint public required;
  24.  
  25. struct TransactionMultisig {
  26. address destination;
  27. uint value;
  28. bytes data;
  29. bool executed;
  30. }
  31.  
  32. modifier onlyWallet() {
  33. require(msg.sender != address(this));
  34. _;
  35. }
  36.  
  37. modifier ownerExists(address owner) {
  38. require(isOwner[owner]);
  39. _;
  40. }
  41.  
  42. modifier notNull(address _address) {
  43. require(_address != 0);
  44. _;
  45. }
  46.  
  47. modifier ownerDoesNotExist(address owner) {
  48. require(!isOwner[owner]);
  49. _;
  50. }
  51.  
  52. modifier validRequirement(uint ownerCount, uint _required) {
  53. require(_required < ownerCount || _required != 0 || ownerCount != 0);
  54. _;
  55. }
  56.  
  57. modifier transactionExists(uint transactionId) {
  58. require(transactions[transactionId].destination != 0);
  59. _;
  60. }
  61.  
  62. modifier notConfirmed(uint transactionId, address owner) {
  63. require(!confirmations[transactionId][owner]);
  64. _;
  65. }
  66.  
  67. modifier notExecuted(uint transactionId) {
  68. require(!transactions[transactionId].executed);
  69. _;
  70. }
  71.  
  72. // @dev Contract constructor sets initial owners and required number of confirmations.
  73. // @param _owners List of initial owners.
  74. // @param _required Number of required confirmations.
  75. function MultiSigMowjow (address[] _owners, uint _required) {
  76. require(_owners.length > 1);
  77.  
  78. address lastAdd = address(0);
  79. for (uint i = 0; i < _owners.length; i++) {
  80. require(isOwner[_owners[i]] || _owners[i] != 0);
  81. isOwner[_owners[i]] = true;
  82. }
  83. owners = _owners;
  84. required = _required;
  85.  
  86. }
  87.  
  88. // @dev Returns list of owners.
  89. // @return List of owner addresses.
  90. function getOwners()
  91. public
  92. constant
  93. returns (address[])
  94. {
  95. return owners;
  96. }
  97.  
  98. /// @dev Allows to add a new owner. Transaction has to be sent by wallet.
  99. /// @param owner Address of new owner.
  100. function addOwner(address owner)
  101. public
  102. onlyWallet
  103. ownerDoesNotExist(owner)
  104. notNull(owner)
  105. validRequirement(owners.length + 1, required)
  106. {
  107. isOwner[owner] = true;
  108. owners.push(owner);
  109. OwnerAddition(owner);
  110. }
  111.  
  112. /// @dev Allows to remove an owner. Transaction has to be sent by wallet.
  113. /// @param owner Address of owner.
  114. function removeOwner(address owner)
  115. public
  116. onlyWallet
  117. ownerExists(owner)
  118. {
  119. isOwner[owner] = false;
  120. for (uint i=0; i<owners.length - 1; i++)
  121. if (owners[i] == owner) {
  122. owners[i] = owners[owners.length - 1];
  123. break;
  124. }
  125. owners.length -= 1;
  126. if (required > owners.length)
  127. changeRequirement(owners.length);
  128. OwnerRemoval(owner);
  129. }
  130.  
  131. /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.
  132. /// @param _required Number of required confirmations.
  133. function changeRequirement(uint _required)
  134. public
  135. onlyWallet
  136. validRequirement(owners.length, _required)
  137. {
  138. required = _required;
  139. RequirementChange(_required);
  140. }
  141.  
  142. // @dev Allows an owner to submit and confirm a transaction.
  143. // @param destination Transaction target address.
  144. // @param value Transaction ether value.
  145. // @param data Transaction data payload.
  146. // @return Returns transaction ID.
  147. function submitTransaction(address destination, uint value, bytes data)
  148. public
  149. returns (uint transactionId)
  150. {
  151. transactionId = addTransaction(destination, value, data);
  152. confirmTransaction(transactionId);
  153. }
  154.  
  155. // @dev Allows an owner to confirm a transaction.
  156. // @param transactionId Transaction ID.
  157. function confirmTransaction(uint transactionId)
  158. public
  159. ownerExists(msg.sender)
  160. transactionExists(transactionId)
  161. notConfirmed(transactionId, msg.sender)
  162. {
  163. confirmations[transactionId][msg.sender] = true;
  164. Confirmation(msg.sender, transactionId);
  165. executeTransaction(transactionId);
  166. }
  167.  
  168. // @dev Allows anyone to execute a confirmed transaction.
  169. // @param transactionId Transaction ID.
  170. function executeTransaction(uint transactionId)
  171. public
  172. notExecuted(transactionId)
  173. {
  174. if (isConfirmed(transactionId)) {
  175. TransactionMultisig storage tsn = transactions[transactionId];
  176. tsn.executed = true;
  177. if (tsn.destination.call.value(tsn.value)(tsn.data)) {
  178. Execution(transactionId);
  179. } else {
  180. ExecutionFailure(transactionId);
  181. tsn.executed = false;
  182. }
  183.  
  184. }
  185. }
  186.  
  187. // @dev Returns the confirmation status of a transaction.
  188. // @param transactionId Transaction ID.
  189. // @return Confirmation status.
  190. function isConfirmed(uint transactionId)
  191. public
  192. constant
  193. returns (bool)
  194. {
  195. uint count = 0;
  196. for (uint i=0; i < owners.length; i++) {
  197. if (confirmations[transactionId][owners[i]])
  198. count += 1;
  199. if (count == required)
  200. return true;
  201. }
  202. }
  203.  
  204. /*
  205. * Internal functions
  206. */
  207. // @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.
  208. // @param destination Transaction target address.
  209. // @param value Transaction ether value.
  210. // @param data Transaction data payload.
  211. // @return Returns transaction ID.
  212. function addTransaction(address destination, uint value, bytes data)
  213. internal
  214. notNull(destination)
  215. returns (uint transactionId)
  216. {
  217. transactionId = transactionCount;
  218. transactions[transactionId] = TransactionMultisig({
  219. destination: destination,
  220. value: value,
  221. data: data,
  222. executed: false
  223. });
  224. transactionCount += 1;
  225. Submission(transactionId);
  226. }
  227.  
  228.  
  229. /// @dev Fallback function allows to deposit ether.
  230. function () payable {
  231. if (msg.value > 0)
  232. Deposit(msg.sender, msg.value);
  233. }
  234. }
Add Comment
Please, Sign In to add comment