🛠️ Development Workflow: Building & Testing Smart Contracts
The Workshop Analogy 🏭
Imagine you’re building a toy robot. You need:
- A workbench to build on (Remix IDE)
- A complete workshop with tools (Hardhat)
- A professional factory with automation (Foundry)
- Ways to test if your robot works (Testing)
- Checking every part was tested (Coverage)
- Finding why it broke (Debugging)
Let’s explore each tool in your smart contract workshop!
1. Remix IDE: Your Online Workbench 🖥️
What Is It?
Remix is like Google Docs, but for smart contracts. Open your browser, and you can start building immediately—no installation needed!
Simple Example:
- You want to write your first smart contract
- Go to remix.ethereum.org
- Start coding in seconds!
Why Developers Love It
graph TD A["Open Browser"] --> B["Go to Remix"] B --> C["Write Code"] C --> D["Compile Instantly"] D --> E["Deploy & Test"] E --> F["See Results!"]
Key Features
| Feature | What It Does |
|---|---|
| File Explorer | Organize your contracts |
| Compiler | Turn code into bytecode |
| Deploy Tab | Put contract on blockchain |
| Debugger | Find problems step-by-step |
Quick Start Code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract HelloWorld {
string public message;
constructor() {
message = "Hello, Web3!";
}
}
When to Use Remix
✅ Learning smart contracts ✅ Quick prototyping ✅ Testing small ideas ✅ Sharing code with others
2. Hardhat Framework: Your Complete Workshop 🔨
What Is It?
Hardhat is like having a complete workshop at home. It gives you ALL the tools you need to build, test, and deploy smart contracts professionally.
Real Life Example:
- Remix = Writing a letter by hand
- Hardhat = Using a word processor with spell-check, auto-save, and templates
Getting Started
# Create new project
mkdir my-project
cd my-project
npm init -y
npm install --save-dev hardhat
npx hardhat init
Project Structure
my-project/
├── contracts/ ← Your smart contracts
├── scripts/ ← Deployment scripts
├── test/ ← Test files
├── hardhat.config.js
└── package.json
Hardhat Magic: Console.log in Solidity!
import "hardhat/console.sol";
contract MyContract {
function doSomething(uint x) public {
console.log("Value of x:", x);
// Now you can see what's happening!
}
}
Why Hardhat?
graph TD A["Hardhat"] --> B["Local Blockchain"] A --> C["Testing Framework"] A --> D["Debugging Tools"] A --> E["Plugin System"] B --> F["Test Without Real Money"] C --> G["Catch Bugs Early"] D --> H["Find Problems Fast"] E --> I["Add Extra Powers"]
3. Foundry Framework: The Professional Factory ⚡
What Is It?
Foundry is like a high-speed factory for smart contracts. It’s FAST because it’s written in Rust, and tests are written in Solidity itself!
Speed Comparison:
- Hardhat tests: 🚗 Car speed
- Foundry tests: 🚀 Rocket speed
The Foundry Toolbox
| Tool | Purpose |
|---|---|
| Forge | Build & test contracts |
| Cast | Talk to the blockchain |
| Anvil | Local test blockchain |
| Chisel | Try code snippets |
Getting Started
# Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup
# Create project
forge init my-foundry-project
Write Tests in Solidity!
// test/Counter.t.sol
import "forge-std/Test.sol";
import "../src/Counter.sol";
contract CounterTest is Test {
Counter counter;
function setUp() public {
counter = new Counter();
}
function testIncrement() public {
counter.increment();
assertEq(counter.number(), 1);
}
}
Run Tests
forge test
# Output: Running tests...
# [PASS] testIncrement()
4. Smart Contract Testing: Making Sure It Works 🧪
Why Test?
Think about it: Smart contracts handle real money. Once deployed, you can’t change them. Testing is not optional—it’s essential!
Story Time:
A developer deployed a contract without proper testing. A bug let hackers steal $50 million. Don’t be that developer!
Types of Tests
graph TD A["Testing Types"] --> B["Unit Tests"] A --> C["Integration Tests"] A --> D["Fuzz Tests"] B --> E["Test one function"] C --> F["Test contracts together"] D --> G["Random inputs find bugs"]
Unit Test Example (Hardhat)
const { expect } = require("chai");
describe("Token", function() {
it("Should mint tokens", async function() {
const Token = await ethers.getContractFactory("Token");
const token = await Token.deploy();
await token.mint(100);
expect(await token.totalSupply()).to.equal(100);
});
});
Fuzz Testing (Foundry)
Fuzz testing = Let the computer try MANY random inputs!
function testFuzz_Withdraw(uint96 amount) public {
// Foundry will try hundreds of random amounts!
vm.assume(amount > 0 && amount <= 1 ether);
vault.deposit{value: amount}();
vault.withdraw(amount);
assertEq(address(vault).balance, 0);
}
5. Test Coverage: Did You Test Everything? 📊
What Is Coverage?
Coverage tells you: “What percentage of your code did your tests actually run?”
Simple Example:
- Your contract has 100 lines of code
- Tests ran through 80 lines
- Coverage = 80%
Why It Matters
graph TD A["Low Coverage"] --> B["Hidden Bugs"] B --> C["Contract Gets Hacked"] C --> D["Money Lost Forever"] E["High Coverage"] --> F["Most Code Tested"] F --> G["Bugs Found Early"] G --> H["Safe Deployment"]
Check Coverage in Hardhat
npx hardhat coverage
Output:
------------|----------|----------|----------|----------|
File | % Stmts | % Branch| % Funcs | % Lines |
------------|----------|----------|----------|----------|
Token.sol | 95.00 | 90.00 | 100.00 | 95.00 |
Vault.sol | 88.00 | 75.00 | 90.00 | 88.00 |
------------|----------|----------|----------|----------|
All files | 91.50 | 82.50 | 95.00 | 91.50 |
------------|----------|----------|----------|----------|
Coverage Types Explained
| Type | What It Measures |
|---|---|
| Statement | Each line of code |
| Branch | Each if/else path |
| Function | Each function called |
| Line | Each executable line |
Coverage in Foundry
forge coverage
The 100% Myth
⚠️ Important: 100% coverage does NOT mean bug-free!
Coverage shows what code RAN, not if the TESTS were good.
Example of Bad Test with 100% Coverage:
function testBad() public {
token.transfer(user, 100);
// Never checks if transfer succeeded!
}
6. Debugging Smart Contracts: Finding the Bug 🔍
The Detective Work
Debugging is like being a detective. Something went wrong—now find out WHY!
Tool 1: Console.log (Hardhat)
The simplest way to see what’s happening:
import "hardhat/console.sol";
function transfer(address to, uint amount) public {
console.log("Sender:", msg.sender);
console.log("Recipient:", to);
console.log("Amount:", amount);
console.log("Balance:", balances[msg.sender]);
// Now you can see each step!
require(balances[msg.sender] >= amount);
balances[msg.sender] -= amount;
balances[to] += amount;
}
Tool 2: Remix Debugger
graph TD A["Transaction Failed"] --> B["Copy TX Hash"] B --> C["Open Remix Debugger"] C --> D["Step Through Code"] D --> E["See Variables at Each Step"] E --> F["Find the Problem!"]
Tool 3: Foundry Traces
forge test -vvvv
Output shows every step:
[PASS] testTransfer()
Traces:
[120000] Token::transfer(user, 100)
├─ [check] balances[sender] >= 100
├─ [update] balances[sender] -= 100
├─ [update] balances[user] += 100
└─ ← true
Common Bug Patterns
| Bug | What Happens | How to Find |
|---|---|---|
| Reentrancy | Contract called again before finishing | Check external calls |
| Overflow | Number gets too big | Use SafeMath or Solidity 0.8+ |
| Access Control | Wrong person can call | Check require statements |
| Logic Error | Wrong calculation | Add console.logs |
Debugging Checklist
- ✅ Read the error message carefully
- ✅ Add console.log statements
- ✅ Use the debugger to step through
- ✅ Check the transaction trace
- ✅ Write a test that reproduces the bug
- ✅ Fix and verify with the test
🎯 Choosing Your Tools
graph TD A["What Do You Need?"] --> B{Learning?} B -->|Yes| C["Start with Remix"] B -->|No| D{Speed Critical?} D -->|Yes| E["Use Foundry"] D -->|No| F["Use Hardhat"] C --> G["Move to Hardhat Later"] E --> H["Best for Pros"] F --> I["Great Plugin Ecosystem"]
Quick Comparison
| Feature | Remix | Hardhat | Foundry |
|---|---|---|---|
| Setup | None | npm install | curl install |
| Speed | Medium | Medium | Very Fast |
| Tests in | N/A | JavaScript | Solidity |
| Best For | Learning | Full Development | Speed & Fuzz |
🚀 Your Learning Path
- Week 1: Play with Remix IDE
- Week 2: Set up Hardhat project
- Week 3: Write your first tests
- Week 4: Try Foundry for speed
- Week 5: Master coverage & debugging
💡 Key Takeaways
Remix = Quick and easy, perfect for learning Hardhat = Professional toolkit with plugins Foundry = Blazing fast, tests in Solidity Testing = Not optional, it’s essential Coverage = Know what you tested Debugging = Be the detective, find the bug
Remember: Every professional smart contract developer uses these tools daily. Master them, and you’ll build contracts people can trust! 🏆
