//sol Wallet // Multi-sig, daily-limited account proxy/wallet. // @authors: // Gav Wood // inheritable "property" contract that enables methods to be protected by requiring the acquiescence of either a // single, or, crucially, each of a number of, designated owners. // usage: // use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by // some number (specified in constructor) of the set of owners (specified in the constructor, modifiable) before the // interior is executed. pragma solidity ^0.4.9; contract WalletEvents { // EVENTS // this contract only has six types of events: it can accept a confirmation, in which case // we record owner and operation (hash) alongside it. event Confirmation(address owner, bytes32 operation); event Revoke(address owner, bytes32 operation); // some others are in the case of an owner changing. event OwnerChanged(address oldOwner, address newOwner); event OwnerAdded(address newOwner); event OwnerRemoved(address oldOwner); // the last one is emitted if the required signatures change event RequirementChanged(uint newRequirement); // Funds has arrived into the wallet (record how much). event Deposit(address _from, uint value); // Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going). event SingleTransact(address owner, uint value, address to, bytes data, address created); // Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going). event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data, address created); // Confirmation still needed for a transaction. event ConfirmationNeeded(bytes32 operation, address initiator, uint value, address to, bytes data); } contract Wallet is WalletEvents { // METHODS // gets called when no other function matches function() payable { // just being sent some cash? if (msg.value > 0) Deposit(msg.sender, msg.value); else if (msg.data.length > 0) _walletLibrary.delegatecall(msg.data); } // Gets an owner by 0-indexed position (using numOwners as the count) function getOwner(uint ownerIndex) constant returns (address) { return address(m_owners[ownerIndex + 1]); } // As return statement unavailable in fallback, explicit the method here function hasConfirmed(bytes32 _operation, address _owner) external constant returns (bool) { return _walletLibrary.delegatecall(msg.data); } function isOwner(address _addr) constant returns (bool) { return _walletLibrary.delegatecall(msg.data); } // FIELDS address constant _walletLibrary = 0x1111111111111111111111111111111111111111; // the number of owners that must confirm the same operation before it is run. uint public m_required; // pointer used to find a free slot in m_owners uint public m_numOwners; uint public m_dailyLimit; uint public m_spentToday; uint public m_lastDay; // list of owners uint[256] m_owners; }