1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| pragma solidity ^0.8.0;
contract MultiSigWallet { address[] public owners; uint public required; struct Transaction { address to; uint value; bytes data; bool executed; } Transaction[] public transactions; mapping(uint => mapping(address => bool)) public confirmations; event Submission(uint indexed transactionId); event Confirmation(address indexed sender, uint indexed transactionId); event Execution(uint indexed transactionId); event Deposit(address indexed sender, uint value); modifier onlyOwner() { require(isOwner(msg.sender), "Not owner"); _; } modifier validRequirement(uint ownerCount, uint _required) { require(_required > 0 && _required <= ownerCount, "Invalid requirement"); _; } constructor(address[] memory _owners, uint _required) validRequirement(_owners.length, _required) { owners = _owners; required = _required; } function isOwner(address addr) public view returns (bool) { for (uint i = 0; i < owners.length; i++) { if (owners[i] == addr) return true; } return false; } function submitTransaction(address _to, uint _value, bytes memory _data) public onlyOwner returns (uint) { uint txIndex = transactions.length; transactions.push(Transaction({ to: _to, value: _value, data: _data, executed: false })); emit Submission(txIndex); confirmTransaction(txIndex); return txIndex; } function confirmTransaction(uint _txIndex) public onlyOwner { require(!confirmations[_txIndex][msg.sender], "Already confirmed"); require(!transactions[_txIndex].executed, "Already executed"); confirmations[_txIndex][msg.sender] = true; emit Confirmation(msg.sender, _txIndex); if (getConfirmationCount(_txIndex) >= required) { executeTransaction(_txIndex); } function executeTransaction(uint _txIndex) public { require(getConfirmationCount(_txIndex) >= required, "Not enough confirmations"); Transaction storage txn = transactions[_txIndex]; txn.executed = true; (bool success, ) = txn.to.call{value: txn.value}(txn.data); require(success, "Transaction failed"); emit Execution(_txIndex); } function getConfirmationCount(uint _txIndex) public view returns (uint) { uint count = 0; if (confirmations[_txIndex][owners[i]]) { count++; } return count; } function getTransactionCount(bool pending, bool executed) view { for (uint i = 0; i < transactions.length; i++) { if (pending && !transactions[i].executed) count++; if (executed && transactions[i].executed) count++; } } receive() external payable { if (msg.value > 0) { emit Deposit(msg.sender, msg.value); }
|