MultisigWallet.sol 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. pragma solidity ^0.4.4;
  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. // kills the contract sending everything to `_to`.
  13. function kill(address _to) onlymanyowners(sha3(msg.data)) external {
  14. suicide(_to);
  15. }
  16. // gets called when no other function matches
  17. function() payable {
  18. // just being sent some cash?
  19. if (msg.value > 0)
  20. Deposit(msg.sender, msg.value);
  21. }
  22. // Outside-visible transact entry point. Executes transaction immediately if below daily spend limit.
  23. // If not, goes into multisig process. We provide a hash on return to allow the sender to provide
  24. // shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
  25. // and _data arguments). They still get the option of using them if they want, anyways.
  26. function execute(address _to, uint _value, bytes _data) external onlyOwner returns (bytes32 _r) {
  27. // first, take the opportunity to check that we're under the daily limit.
  28. if (underLimit(_value)) {
  29. SingleTransact(msg.sender, _value, _to, _data);
  30. // yes - just execute the call.
  31. if (!_to.call.value(_value)(_data)) {
  32. throw;
  33. }
  34. return 0;
  35. }
  36. // determine our operation hash.
  37. _r = sha3(msg.data, block.number);
  38. if (!confirm(_r) && txs[_r].to == 0) {
  39. txs[_r].to = _to;
  40. txs[_r].value = _value;
  41. txs[_r].data = _data;
  42. ConfirmationNeeded(_r, msg.sender, _value, _to, _data);
  43. }
  44. }
  45. // confirm a transaction through just the hash. we use the previous transactions map, txs, in order
  46. // to determine the body of the transaction from the hash provided.
  47. function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) {
  48. if (txs[_h].to != 0) {
  49. if (!txs[_h].to.call.value(txs[_h].value)(txs[_h].data)) {
  50. throw;
  51. }
  52. MultiTransact(msg.sender, _h, txs[_h].value, txs[_h].to, txs[_h].data);
  53. delete txs[_h];
  54. return true;
  55. }
  56. }
  57. function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data)) external {
  58. _setDailyLimit(_newLimit);
  59. }
  60. function resetSpentToday() onlymanyowners(sha3(msg.data)) external {
  61. _resetSpentToday();
  62. }
  63. // INTERNAL METHODS
  64. function clearPending() internal {
  65. uint length = pendingsIndex.length;
  66. for (uint i = 0; i < length; ++i) {
  67. delete txs[pendingsIndex[i]];
  68. }
  69. super.clearPending();
  70. }
  71. // FIELDS
  72. // pending transactions we have at present.
  73. mapping (bytes32 => Transaction) txs;
  74. }