A multi-signature wallet needs more than one person to approve a transaction. This makes it safer because no single person can spend money alone.
Multi-signature wallet concept in Blockchain / Solidity
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
Blockchain / Solidity
multiSigWallet = {
owners: [address1, address2, address3],
requiredSignatures: 2,
transactions: [],
submitTransaction(tx) { ... },
confirmTransaction(txId, owner) { ... },
executeTransaction(txId) { ... }
}owners is the list of people who can approve transactions.
requiredSignatures is how many approvals are needed to send money.
Examples
Blockchain / Solidity
owners = ['Alice', 'Bob', 'Carol'] requiredSignatures = 2
Blockchain / Solidity
owners = ['Dave', 'Eve'] requiredSignatures = 2
Sample Program
This program creates a multi-signature wallet with three owners. It submits a transaction, then owners confirm it. The transaction only executes after enough owners approve.
Blockchain / Solidity
class MultiSigWallet: def __init__(self, owners, required_signatures): self.owners = owners self.required_signatures = required_signatures self.transactions = {} self.confirmations = {} self.tx_count = 0 def submit_transaction(self, tx): tx_id = self.tx_count self.transactions[tx_id] = tx self.confirmations[tx_id] = set() self.tx_count += 1 print(f"Transaction {tx_id} submitted: {tx}") return tx_id def confirm_transaction(self, tx_id, owner): if owner not in self.owners: print(f"{owner} is not an owner.") return if tx_id not in self.transactions: print(f"Transaction {tx_id} does not exist.") return self.confirmations[tx_id].add(owner) print(f"{owner} confirmed transaction {tx_id}.") def execute_transaction(self, tx_id): if tx_id not in self.transactions: print(f"Transaction {tx_id} does not exist.") return if len(self.confirmations[tx_id]) >= self.required_signatures: print(f"Transaction {tx_id} executed: {self.transactions[tx_id]}") del self.transactions[tx_id] del self.confirmations[tx_id] else: print(f"Transaction {tx_id} needs more confirmations.") # Example usage owners = ['Alice', 'Bob', 'Carol'] wallet = MultiSigWallet(owners, 2) tx_id = wallet.submit_transaction('Send 10 coins to Dave') wallet.confirm_transaction(tx_id, 'Alice') wallet.execute_transaction(tx_id) # Not enough confirmations wallet.confirm_transaction(tx_id, 'Bob') wallet.execute_transaction(tx_id) # Now it executes
Important Notes
Multi-signature wallets increase security by requiring multiple approvals.
Each owner has a unique key to sign transactions.
Without enough confirmations, transactions cannot be executed.
Summary
Multi-signature wallets need several people to approve transactions.
This protects funds from being spent by one person alone.
They are useful for groups or companies managing shared money.
Practice
1. What is the main purpose of a
multi-signature wallet in blockchain?easy
Solution
Step 1: Understand the multi-signature wallet concept
A multi-signature wallet requires more than one person to approve a transaction before it can be executed.Step 2: Identify the main purpose
This setup protects funds by preventing a single user from spending money alone, increasing security.Final Answer:
To require multiple approvals before spending funds -> Option AQuick Check:
Multi-signature = multiple approvals [OK]
Hint: Multi-signature means multiple people must approve [OK]
Common Mistakes:
- Thinking it speeds up transactions
- Believing one user controls all funds
- Confusing it with single-key wallets
2. Which of the following is the correct way to define a multi-signature wallet threshold in Solidity?
easy
Solution
Step 1: Identify correct data type for threshold
The threshold is a number representing how many signatures are needed, so an unsigned integer likeuint8is appropriate.Step 2: Check syntax correctness
Assigning a number directly touint8is correct. Using quotes or wrong types causes errors.Final Answer:
uint8 threshold = 1; -> Option DQuick Check:
Threshold is a number, use uint8 [OK]
Hint: Threshold is a number, use uint type without quotes [OK]
Common Mistakes:
- Using quotes around numbers
- Assigning string type to threshold
- Using boolean type for threshold
3. Given this Solidity snippet for a multi-signature wallet, what will be the value of
isApproved after calling approveTransaction(1, msg.sender) if the threshold is 2 and only one approval is made?mapping(uint => mapping(address => bool)) approvals;
uint8 threshold = 2;
function approveTransaction(uint txId, address approver) public {
approvals[txId][approver] = true;
}
function isApproved(uint txId) public view returns (bool) {
uint count = 0;
for (uint i = 0; i < owners.length; i++) {
if (approvals[txId][owners[i]]) {
count++;
}
}
return count >= threshold;
}medium
Solution
Step 1: Understand approval counting logic
The function counts how many owners approved the transaction and compares it to the threshold.Step 2: Analyze given scenario
Only one approval is made but threshold is 2, socountis 1 which is less than 2.Final Answer:
false -> Option BQuick Check:
Approvals < threshold = false [OK]
Hint: Approval count must meet threshold to be true [OK]
Common Mistakes:
- Assuming one approval is enough
- Ignoring threshold comparison
- Confusing approval mapping structure
4. Identify the bug in this Solidity function for approving transactions in a multi-signature wallet:
function approveTransaction(uint txId) public {
approvals[txId][msg.sender] = true;
if (isApproved(txId)) {
executeTransaction(txId);
}
}
function isApproved(uint txId) public view returns (bool) {
uint count = 0;
for (uint i = 0; i <= owners.length; i++) {
if (approvals[txId][owners[i]]) {
count++;
}
}
return count >= threshold;
}medium
Solution
Step 1: Check the for loop boundary
The loop usesi <= owners.length, which causes out-of-bounds access because array indices go from 0 to length-1.Step 2: Correct the loop condition
Changing toi < owners.lengthprevents accessing invalid index and runtime errors.Final Answer:
Loop condition should be < instead of <= -> Option CQuick Check:
Array index out of bounds fixed by < [OK]
Hint: Array loops use < length, not <= length [OK]
Common Mistakes:
- Using <= in loops causing errors
- Ignoring array index limits
- Thinking event emission fixes logic bugs
5. You want to create a multi-signature wallet that requires 3 out of 5 owners to approve a transaction. Which approach correctly enforces this rule in Solidity?
mapping(uint => mapping(address => bool)) approvals;
address[5] owners;
uint8 threshold = 3;
function executeTransaction(uint txId) public {
uint count = 0;
for (uint i = 0; i < owners.length; i++) {
if (approvals[txId][owners[i]]) {
count++;
}
}
if (count >= threshold) {
// execute the transaction
} else {
revert("Not enough approvals");
}
}hard
Solution
Step 1: Analyze the approval counting logic
The code counts how many owners approved the transaction by checking theapprovalsmapping for each owner.Step 2: Check threshold enforcement
If the count is at least the threshold (3), the transaction executes; otherwise, it reverts with an error.Final Answer:
This code correctly enforces the 3-of-5 approval rule -> Option AQuick Check:
Count approvals >= threshold = enforce rule [OK]
Hint: Count approvals, compare with threshold, revert if not met [OK]
Common Mistakes:
- Setting threshold incorrectly
- Looping over wrong data structure
- Using return instead of revert for errors
