# Comment Passer du Développement Web2 au Web3
Vous savez coder. Maintenant il faut apprendre à coder où chaque bug coûte $1M.
Le Shift Mental
Web2 : Move Fast, Break Things
// Web2 : si ça casse, rollback
app.post('/transfer', (req, res) => {
const { from, to, amount } = req.body;
db.users.update(from, { balance: balance - amount });
db.users.update(to, { balance: balance + amount });
// Bug ? Rollback la DB, hotfix, redeploy
// Downtime = 5min, users râlent, vie continue
});
Web3 : Move Slow, Don't Break Anything
// Web3 : si ça casse, fonds perdus à jamais
contract Token {
mapping(address => uint256) public balances;
function transfer(address to, uint256 amount) external {
balances[msg.sender] -= amount;
balances[to] += amount;
// Bug ? Pas de rollback. Fonds gone.
// Exploit public en 5min, $10M drainés, protocol mort
}
}
Différence clé : Web3 = immuable, déterministe, public, adversarial.
Fondamentaux à Apprendre
1. Solidity (Langage)
// Concepts core (dans l'ordre) :
// 1. Types : uint, address, mapping, array
// 2. Visibility : public, external, internal, private
// 3. Payable : recevoir ETH
// 4. State vs memory vs calldata
// 5. Events : logging on-chain
// 6. Modifiers : access control
// 7. Errors : require, revert, custom errors
// 8. Inheritance : is, virtual, override
// Pratique : coder un ERC20 from scratch
contract MyToken {
mapping(address => uint256) public balanceOf;
function transfer(address to, uint256 amount) external {
require(balanceOf[msg.sender] >= amount, "Insufficient balance");
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
}
}
// Ne lisez PAS CryptoZombies. Outdated + mauvaises pratiques.
// Lisez : Solidity docs officielles + OpenZeppelin contracts.
2. EVM (Execution Model)
Key concepts :
- Gas : chaque opération coûte. Loop infinie = impossible.
- Storage : persistent, cher ($20k pour 32 bytes à high gas).
- Memory : temporaire, cheap.
- Calldata : read-only input, cheapest.
- Stack : max 16 items (stack-too-deep errors).
// Example : pourquoi storage est cher
uint256 public count; // Storage : 20k gas pour write
function increment() external {
count++; // SSTORE = 20k gas
}
// Optimisation : batch writes
function incrementN(uint256 n) external {
uint256 temp = count; // 1 SLOAD
temp += n;
count = temp; // 1 SSTORE
// Au lieu de N SSTOREs
}
3. Foundry (Stack)
# Oubliez Hardhat/Truffle. Foundry = standard 2026.
# Install
curl -L https://foundry.paradigm.xyz | bash
foundryup
# Nouveau projet
forge init my-project
cd my-project
# Structure
src/ # Contracts
test/ # Tests (Solidity, pas JS !)
script/ # Deploy scripts
lib/ # Dependencies (git submodules)
# Test
forge test
# Deploy
forge create src/MyContract.sol:MyContract --rpc-url $RPC --private-key $PK
# Verify
forge verify-contract <address> src/MyContract.sol:MyContract --chain mainnet --etherscan-api-key $KEY
Séquence d'Apprentissage
Phase 1 : Lire du Code (1-2 semaines)
// Lisez Uniswap V2 (simple, ~500 LOC total)
// Fichiers :
// 1. UniswapV2Pair.sol : AMM logic (mint, burn, swap)
// 2. UniswapV2Router.sol : user-facing entry point
// Questions à répondre :
// - Comment le prix est calculé (x*y=k) ?
// - Pourquoi mint() a un minimum liquidity ?
// - Comment swap() évite les reentrancy ?
// Ligne par ligne. Prenez des notes.
Phase 2 : Écrire du Code (2-3 semaines)
// Projet 1 : ERC20 complet
// - Mint, burn, transfer, approve, transferFrom
// - Events, errors
// - Tests Foundry (100% coverage)
// Projet 2 : Vault simple
// - Deposit ETH/ERC20
// - Withdraw avec shares (comme ERC4626)
// - Access control (owner only withdraw fees)
// Projet 3 : NFT marketplace
// - List NFT for sale
// - Buy NFT
// - Cancel listing
// - Royalties (ERC2981)
Phase 3 : Fork et Modifier (2-3 semaines)
# Fork Compound v2 (lending protocol)
git clone https://github.com/compound-finance/compound-protocol
cd compound-protocol
# Modifiez :
# 1. Ajoutez un nouveau collatéral (ex: stETH)
# 2. Changez le interest rate model
# 3. Ajoutez un liquidation bonus
# 4. Testez avec Foundry fork tests
forge test --fork-url $MAINNET_RPC
Phase 4 : Auditer (3-4 semaines)
# Trouvez des bugs dans de vrais protocols
# 1. Code4rena past contests
# - Lisez les findings High/Medium
# - Essayez de les trouver vous-même (avant de lire)
# 2. Damn Vulnerable DeFi
# - 15 challenges (flash loans, governance, oracles...)
# - Solutions disponibles, mais essayez d'abord
# 3. Ethernaut
# - 30 levels (reentrancy, overflow, delegatecall...)
Stack Frontend (Web3-Specific)
// Ethers v6 ou Viem (pas Ethers v5, outdated)
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
const client = createPublicClient({
chain: mainnet,
transport: http()
})
// Lire un contract
const balance = await client.readContract({
address: '0x...',
abi: ERC20_ABI,
functionName: 'balanceOf',
args: ['0x...']
})
// Écrire (nécessite wallet)
import { createWalletClient } from 'viem'
const wallet = createWalletClient({ chain: mainnet, transport: http() })
const hash = await wallet.writeContract({
address: '0x...',
abi: ERC20_ABI,
functionName: 'transfer',
args: ['0xRecipient', 1000000n]
})
// Wagmi : hooks React pour wallets
import { useAccount, useWriteContract } from 'wagmi'
function TransferButton() {
const { address } = useAccount()
const { write } = useWriteContract()
return (
<button onClick={() => write({
address: TOKEN_ADDRESS,
abi: ERC20_ABI,
functionName: 'transfer',
args: [recipient, amount]
})}>
Transfer
</button>
)
}
Pièges Courants
1. CryptoZombies Only
❌ "J'ai fait CryptoZombies, je suis dev Web3"
✅ CryptoZombies = intro seulement
Vous devez lire de vrais protocols (Uniswap, Aave, Compound)
+ écrire vos propres contracts
+ trouver des bugs
2. Ignorer la Sécurité
// ❌ Code qui "marche"
function withdraw() external {
uint256 balance = balances[msg.sender];
(bool success, ) = msg.sender.call{value: balance}("");
require(success);
balances[msg.sender] = 0; // ← Trop tard, déjà reentered
}
// ✅ Code qui marche ET est sûr
function withdraw() external {
uint256 balance = balances[msg.sender];
balances[msg.sender] = 0; // Checks-Effects-Interactions
(bool success, ) = msg.sender.call{value: balance}("");
require(success);
}
Règle : la sécurité n'est PAS optionnelle. Apprenez les patterns (CEI, ReentrancyGuard, etc.) dès le début.
3. Pas de Tests
# ❌ "Je teste en local avec Remix"
# ✅ Tests Foundry automatisés
forge test --match-test testTransfer -vvv
# Coverage
forge coverage
# Fuzz testing
function testTransferFuzz(address to, uint256 amount) public {
vm.assume(to != address(0));
vm.assume(amount <= totalSupply);
// ...
}
Portfolio Pieces
Pour être hireable, montrez :
1. GitHub avec 3-5 projets Solidity
- ERC20/721 custom
- DeFi protocol (DEX, lending, staking)
- Tests (>80% coverage)
Bug bounty submissions (1-2)
- Même Low/Medium OK
- Montre que vous pensez sécurité
Contributions open-source
- Fix un bug dans OpenZeppelin
- Ajouter une feature à un SDK
Blog posts techniques (2-3)
- Deep dive sur un protocol
- Post-mortem d'un hack
- Tutorial avancé
Timeline Premier Job
Mois 1-2 : Fondamentaux (Solidity + EVM + Foundry)
Mois 3-4 : Projets perso (ERC20, vault, marketplace)
Mois 5-6 : Auditing practice (Damn Vulnerable DeFi, C4 past contests)
Mois 7 : Portfolio polish (README, docs, deploy sur testnet)
Mois 8+ : Job hunt (ou freelance sur Gitcoin/Bountycaster)
Réaliste : 6-9 mois pour premier job junior
Optimiste : 4-5 mois si vous codez full-time
Pessimiste : 12+ mois si part-time
Ressources
Docs :
- Solidity docs (docs.soliditylang.org)
- Foundry book (book.getfoundry.sh)
- Ethereum.org/developers
Code :
- Uniswap v2/v3 (github.com/Uniswap)
- Aave v3 (github.com/aave/aave-v3-core)
- OpenZeppelin contracts (github.com/OpenZeppelin/openzeppelin-contracts)
Practice :
- Damn Vulnerable DeFi (damnvulnerabledefi.xyz)
- Ethernaut (ethernaut.openzeppelin.com)
- Code4rena (code4rena.com)
Community :
- /r/ethdev (Reddit)
- Foundry Telegram
- Secureum Discord
Verdict
Web2 → Web3 = possible, mais pas trivial. Attendez-vous à 6+ mois de grind.
La bonne nouvelle : la demande explose, l'offre est faible. Si vous êtes sérieux, vous trouverez un job.
Commencez aujourd'hui. Lisez Uniswap v2. Puis codez votre propre AMM.