Why testing prevents costly bugs in Blockchain / Solidity - Performance Analysis
Testing blockchain code helps catch problems early before they cause big issues.
We want to see how testing steps affect the time it takes to run the code as it grows.
Analyze the time complexity of the following blockchain testing code snippet.
function testTransactions(transactions) {
for (let i = 0; i < transactions.length; i++) {
if (!validate(transactions[i])) {
return false;
}
}
return true;
}
function validate(tx) {
// simple check for example
return tx.amount > 0 && tx.signature !== '';
}
This code tests each transaction to make sure it is valid before processing.
- Primary operation: Looping through each transaction in the list.
- How many times: Once for each transaction, until an invalid one is found or all are checked.
As the number of transactions grows, the time to test them grows roughly the same way.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 validations |
| 100 | About 100 validations |
| 1000 | About 1000 validations |
Pattern observation: The work grows directly with the number of transactions.
Time Complexity: O(n)
This means the time to test grows in a straight line as the number of transactions grows.
[X] Wrong: "Testing all transactions takes the same time no matter how many there are."
[OK] Correct: More transactions mean more checks, so testing time grows with input size.
Understanding how testing scales helps you write safer blockchain code and shows you think about real-world costs.
"What if the validate function itself called another loop over transaction details? How would the time complexity change?"
Practice
Solution
Step 1: Understand blockchain risks
Blockchain handles real assets and trust, so bugs can cause big losses.Step 2: Role of testing
Testing finds bugs early, preventing costly mistakes before deployment.Final Answer:
Because it helps find bugs early to avoid costly mistakes -> Option AQuick Check:
Testing prevents costly bugs = C [OK]
- Thinking blockchain code never changes
- Believing testing slows development
- Ignoring real asset risks
Solution
Step 1: Recall Solidity function syntax
Functions start with 'function', name, visibility, and body in braces.Step 2: Check options
function testBalance() public { /* test code */ } matches Solidity syntax with 'public' visibility for test functions.Final Answer:
function testBalance() public { /* test code */ } -> Option BQuick Check:
Solidity test function syntax = B [OK]
- Using Python syntax in Solidity
- Missing 'function' keyword
- Using wrong visibility for test functions
uint balance = 100;
function testWithdraw() public {
uint amount = 50;
balance -= amount;
assert(balance == 50);
}What will happen when
testWithdraw() runs?Solution
Step 1: Analyze balance update
Initial balance is 100, subtract 50, new balance is 50.Step 2: Check assertion
Assert checks balance == 50, which is true, so test passes.Final Answer:
The test passes because balance equals 50 after withdrawal -> Option AQuick Check:
balance after subtract 50 = 50 [OK]
- Assuming balance is unchanged
- Confusing compile errors with runtime logic
- Ignoring assert condition
function testWithdraw() public {
uint balance = 100;
uint amount = 150;
balance -= amount;
assert(balance >= 0);
}What is the main problem with this test?
Solution
Step 1: Check balance subtraction
Subtracting 150 from 100 causes underflow (negative balance).Step 2: Understand Solidity behavior
Solidity unsigned integers cannot be negative; underflow causes error or wrap.Final Answer:
It allows balance to go negative, which is invalid in Solidity -> Option CQuick Check:
Unsigned int underflow = error [OK]
- Ignoring unsigned integer limits
- Assuming assert always passes
- Missing visibility keyword
Solution
Step 1: Understand test coverage needs
Testing only successes misses bugs in failure cases.Step 2: Importance of failure tests
Tests for failed transfers catch edge cases and prevent costly errors.Final Answer:
Write tests that check both successful and failed transfers -> Option DQuick Check:
Test successes and failures = D [OK]
- Testing only success cases
- Skipping automated tests
- Testing after deployment too late
Ready to prove it?
Pass the test and this pattern moves unknown
