# MultiSig Wallet **Published by:** [gachengoh](https://paragraph.com/@gachengoh/) **Published on:** 2022-12-04 **URL:** https://paragraph.com/@gachengoh/multisig-wallet ## Content This post is implementing a multisig wallet in solidity,where there must be a number of people to authorize transfer of funds from the wallet.// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; contract MultisigWallet { event Deposit (address indexed sender,uint amount,uint balance); event SubmitingTransaction(address indexed owner, uint indexed txIndex, address indexed to, uint value, bytes data); event ConfirmingTransaction( address indexed owner, uint indexed txIndex); event RevokingConfirmation(address indexed owner, uint indexed txIndex); event ExecutingTransaction(address indexed owner, uint indexed txIndex); //State Variables. address[] public owners; mapping(address => bool) public isOwner; uint public numConfirmationsRequired; struct Transaction { address to; uint value; bytes data; bool executed; uint numConfirmations; } Transaction [] public transactions; // mapping from tx index => owner => bool mapping(uint => mapping(address => bool)) public isConfirmed; constructor(address [] memory _owners, uint _numConfirmationsRequired) { require(_owners.length > 0,"Owners Required"); require(_numConfirmationsRequired > 0 && _numConfirmationsRequired <= _owners.length, "Invalid number of required Confirmations"); for (uint i = 0; i < _owners.length; i++){ address owner = _owners[i]; require(owner != address(0), "invalid Owner"); require(!isOwner[owner], "Owner is not unique"); isOwner[owner] = true; owners.push(owner); } numConfirmationsRequired = _numConfirmationsRequired; } modifier onlyOwner () { require(isOwner[msg.sender], "Not Owner"); _; } modifier txExists(uint _txIndex) { require(_txIndex < transactions.length, "Transaction does not exist"); _; } modifier notExecuted(uint _txIndex) { require(!transactions[_txIndex].executed, "Transactions already executed"); _; } modifier notconfirmed(uint _txIndex){ require(!isConfirmed[_txIndex][msg.sender], "tx already confirmed"); _; } receive() external payable { emit Deposit(msg.sender, msg.value, address(this).balance); } function deposit() external payable { emit Deposit (msg.sender,msg.value,address(this).balance); } function submitTransaction(address _to, uint _value, bytes memory _data) public onlyOwner { uint txIndex = transactions.length; transactions.push(Transaction({ to: _to, value: _value, data: _data, executed: false, numConfirmations: 0 })); emit SubmitingTransaction(msg.sender, txIndex, _to, _value, _data); } function confirmTransaction(uint _txIndex) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) notconfirmed(_txIndex){ Transaction storage transaction = transactions[_txIndex]; isConfirmed[_txIndex][msg.sender] = true; transaction.numConfirmations += 1; emit ConfirmingTransaction( msg.sender, _txIndex); } function executeTransaction(uint _txIndex) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) { Transaction storage transaction = transactions[_txIndex]; require(transaction.numConfirmations >= numConfirmationsRequired,"Cannot Execute Transaction"); transaction.executed = true; (bool success,) = transaction.to.call{value: transaction.value}(transaction.data); require(success, "tx failed"); emit ExecutingTransaction(msg.sender, _txIndex); } function revokeConfirmation(uint _txIndex) public onlyOwner txExists(_txIndex) notExecuted(_txIndex){ Transaction storage transaction = transactions [_txIndex]; require(isConfirmed[_txIndex][msg.sender], "Transaction not confirmed"); transaction.numConfirmations -= 1; isConfirmed[_txIndex][msg.sender] = false; emit RevokingConfirmation(msg.sender, _txIndex); } function getOwners() public view returns (address[] memory) { return owners; } function getTransactionCount() public view returns (uint) { return transactions.length; } } ## Publication Information - [gachengoh](https://paragraph.com/@gachengoh/): Publication homepage - [All Posts](https://paragraph.com/@gachengoh/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@gachengoh): Subscribe to updates