MultisigWallet.sol 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. pragma solidity ^0.4.11;
  2. import "./ownership/Multisig.sol";
  3. import "./ownership/Shareable.sol";
  4. import "./DayLimit.sol";
  5. /**
  6. * MultisigWallet
  7. * Usage:
  8. * bytes32 h = Wallet(w).from(oneOwner).execute(to, value, data);
  9. * Wallet(w).from(anotherOwner).confirm(h);
  10. */
  11. contract MultisigWallet is Multisig, Shareable, DayLimit {
  12. struct Transaction {
  13. address to;
  14. uint256 value;
  15. bytes data;
  16. }
  17. /**
  18. * Constructor, sets the owners addresses, number of approvals required, and daily spending limit
  19. * @param _owners A list of owners.
  20. * @param _required The amount required for a transaction to be approved.
  21. */
  22. function MultisigWallet(address[] _owners, uint256 _required, uint256 _daylimit)
  23. Shareable(_owners, _required)
  24. DayLimit(_daylimit) { }
  25. /**
  26. * @dev destroys the contract sending everything to `_to`.
  27. */
  28. function destroy(address _to) onlymanyowners(keccak256(msg.data)) external {
  29. selfdestruct(_to);
  30. }
  31. /**
  32. * @dev Fallback function, receives value and emits a deposit event.
  33. */
  34. function() payable {
  35. // just being sent some cash?
  36. if (msg.value > 0)
  37. Deposit(msg.sender, msg.value);
  38. }
  39. /**
  40. * @dev Outside-visible transaction entry point. Executes transaction immediately if below daily
  41. * spending limit. If not, goes into multisig process. We provide a hash on return to allow the
  42. * sender to provide shortcuts for the other confirmations (allowing them to avoid replicating
  43. * the _to, _value, and _data arguments). They still get the option of using them if they want,
  44. * anyways.
  45. * @param _to The receiver address
  46. * @param _value The value to send
  47. * @param _data The data part of the transaction
  48. */
  49. function execute(address _to, uint256 _value, bytes _data) external onlyOwner returns (bytes32 _r) {
  50. // first, take the opportunity to check that we're under the daily limit.
  51. if (underLimit(_value)) {
  52. SingleTransact(msg.sender, _value, _to, _data);
  53. // yes - just execute the call.
  54. if (!_to.call.value(_value)(_data)) {
  55. revert();
  56. }
  57. return 0;
  58. }
  59. // determine our operation hash.
  60. _r = keccak256(msg.data, block.number);
  61. if (!confirm(_r) && txs[_r].to == 0) {
  62. txs[_r].to = _to;
  63. txs[_r].value = _value;
  64. txs[_r].data = _data;
  65. ConfirmationNeeded(_r, msg.sender, _value, _to, _data);
  66. }
  67. }
  68. /**
  69. * @dev Confirm a transaction by providing just the hash. We use the previous transactions map,
  70. * txs, in order to determine the body of the transaction from the hash provided.
  71. * @param _h The transaction hash to approve.
  72. */
  73. function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) {
  74. if (txs[_h].to != 0) {
  75. assert(txs[_h].to.call.value(txs[_h].value)(txs[_h].data));
  76. MultiTransact(msg.sender, _h, txs[_h].value, txs[_h].to, txs[_h].data);
  77. delete txs[_h];
  78. return true;
  79. }
  80. }
  81. /**
  82. * @dev Updates the daily limit value.
  83. * @param _newLimit uint256 to represent the new limit.
  84. */
  85. function setDailyLimit(uint256 _newLimit) onlymanyowners(keccak256(msg.data)) external {
  86. _setDailyLimit(_newLimit);
  87. }
  88. /**
  89. * @dev Resets the value spent to enable more spending
  90. */
  91. function resetSpentToday() onlymanyowners(keccak256(msg.data)) external {
  92. _resetSpentToday();
  93. }
  94. // INTERNAL METHODS
  95. /**
  96. * @dev Clears the list of transactions pending approval.
  97. */
  98. function clearPending() internal {
  99. uint256 length = pendingsIndex.length;
  100. for (uint256 i = 0; i < length; ++i) {
  101. delete txs[pendingsIndex[i]];
  102. }
  103. super.clearPending();
  104. }
  105. // FIELDS
  106. // pending transactions we have at present.
  107. mapping (bytes32 => Transaction) txs;
  108. }