diff --git a/docs/pedagogie/fiche-soutenance-tokenizer.md b/docs/pedagogie/fiche-soutenance-tokenizer.md index c772d6d..0b8ec06 100644 --- a/docs/pedagogie/fiche-soutenance-tokenizer.md +++ b/docs/pedagogie/fiche-soutenance-tokenizer.md @@ -68,6 +68,24 @@ J’ai développé avec Hardhat 3 : compilation, deux tests automatisés, déplo | Page token | https://testnet.bscscan.com/token/0x0c76df26A1149fDc22C8f994975705271b070fF4 | supply, holders, transfers | | Tests | 2 tests Mocha, tous verts | `code/test/FGC42Forge.ts` | +### Chain ID — testnet **97** vs mainnet **56** (BNB Smart Chain) + +Oui : pour **BNB Smart Chain** (BSC), les identifiants officiels sont : + +| Réseau | Chain ID | Monnaie gas | Explorateur | Projet FGC42Forge | +|--------|----------|-------------|-------------|-------------------| +| **BSC Testnet** | **97** | **tBNB** (sans valeur réelle) | `testnet.bscscan.com` | **Oui** — seul réseau utilisé | +| **BSC Mainnet** | **56** | **BNB** (vraie valeur) | `bscscan.com` | **Non** — sujet = pas d’argent réel | + +**À retenir à l’oral :** + +- Ton contrat et tes FG42 existent **uniquement** sur le testnet (**97**). Rien n’est déployé sur le mainnet (**56**). +- MetaMask doit afficher **BNB Smart Chain Testnet** et **97** avant toute démo. Si tu es sur **56**, tu ne verras pas le bon contrat ni les bons FG42 (autre chaîne, autre état). +- Ton **adresse compte** `0xB6bE…` est la **même** sur 97 et 56 (même clé EVM), mais les soldes et les contrats ne sont **pas** les mêmes : le testnet et le mainnet sont deux registres séparés. +- Pour comparaison (hors BSC) : Ethereum mainnet = chainId **1**. Ce n’est pas la chaîne du projet, mais le même type d’adresse `0x`. + +Les valeurs **97** et **56** sont dans le README, `deployment/addresses.json` (`chainId: 97`) et la config MetaMask documentée dans `documentation/README.md`. + **18 décimales** : en interne la blockchain ne stocke pas « 1,5 FG42 ». Elle stocke un entier. 1 FG42 affiché = `1 * 10^18` unités. Le million du constructeur, c’est donc `1_000_000 * 10^18`. MetaMask fait la conversion pour l’affichage. Si on oublie les décimales, on croit transférer 1 jeton alors qu’on transfère une fraction infime, ou l’inverse. --- @@ -210,6 +228,48 @@ MetaMask → wallet utilisateur : import FG42, transfer, g | **Lien suivant** | Le compilateur (via Hardhat) inclut ces fichiers ; **BscScan** voit tout via `FGC42Forge_flat.sol`. | | **Phrase soutenance** | « J’ai choisi OpenZeppelin pour respecter le standard sans réinventer les fonctions sensibles. » | +#### Détail OpenZeppelin — paquet, ERC20, Ownable (v5) + +**Installation.** Paquet npm `@openzeppelin/contracts` (version **5.x**, ex. `^5.6.1` dans `package.json`). Installé avec `npm install @openzeppelin/contracts`. Les fichiers `.sol` vivent dans `node_modules/@openzeppelin/contracts/` ; tu ne les édites pas. Au **deploy**, le compilateur **fusionne** ton contrat et OpenZeppelin en **un seul bytecode** à l’adresse `0x0c76…` : il n’y a pas un « contrat OpenZeppelin » séparé sur la chaîne, seulement **FGC42Forge** qui contient ce code. + +**Pourquoi OpenZeppelin plutôt que tout écrire ?** L’ERC-20 est une norme avec des détails faciles à rater (soldes, `allowance`, événements `Transfer` / `Approval`, protection contre transfert vers adresse nulle, `revert` si solde insuffisant). OpenZeppelin est une implémentation **largement utilisée et auditée** ; le sujet attend un standard de chaîne (BEP-20), pas une réécriture amateur de `transfer`. + +**Classe `ERC20` — ce que ton contrat hérite (tu ne le réécris pas dans `FGC42Forge.sol`) :** + +| Fonction / donnée | Rôle | Utilisé en démo ? | +|-------------------|------|-------------------| +| `name()` | `FGC42Forge` | Oui — MetaMask, BscScan | +| `symbol()` | `FG42` | Oui | +| `decimals()` | `18` (défaut OZ) | Oui — affichage wallet | +| `totalSupply()` | 1 000 000 × 10¹⁸ après le constructeur | Oui — page token | +| `balanceOf(adresse)` | Solde d’un compte | Oui | +| `transfer(dest, amount)` | Envoyer ses propres jetons | Oui — MetaMask | +| `approve(spender, amount)` | Autoriser un tiers à dépenser | Non en démo (hérité, standard) | +| `transferFrom(...)` | Dépense via `allowance` | Non en démo (hérité) | +| `allowance(owner, spender)` | Plafond d’autorisation | Non en démo | +| Événement `Transfer` | Trace from / to / value | Oui — test Hardhat + BscScan | +| `_mint(account, amount)` | **Interne** — créer des jetons | **Une fois** dans ton constructeur | + +Tu appelles **`_mint` une seule fois** dans le constructeur. OpenZeppelin ne te force pas à exposer un `mint()` public : tant que tu n’ajoutes pas de fonction publique qui rappelle `_mint`, personne ne peut augmenter l’offre après le deploy. + +**Classe `Ownable` (OpenZeppelin v5) — administration :** + +| Élément | Comportement dans FGC42Forge | +|---------|------------------------------| +| Constructeur `Ownable(msg.sender)` | Le **déployeur** devient `owner` dès le deploy | +| `owner()` | Lecture de l’adresse admin (souvent FGC_account) | +| `transferOwnership(nouveau)` | L’owner peut céder le rôle (personne ne peut mint FG42 via ça) | +| `renounceOwnership()` | L’owner peut renoncer (plus d’owner) | +| Modificateur `onlyOwner` | Restreint une fonction à l’owner — **tu ne l’utilises sur aucune fonction custom** | + +**Point soutenance :** `Ownable` montre que tu as pensé à « qui administre le contrat ». Dans **ton** design, l’owner **ne crée pas** de FG42 supplémentaires et **ne vole pas** les soldes : il n’y a pas de fonction sensible protégée par `onlyOwner` dans ton fichier. + +**v4 vs v5 (piège classique).** En OpenZeppelin **v5**, `Ownable` exige l’owner initial dans le constructeur : `Ownable(msg.sender)`. En v4, le owner était parfois fixé différemment. Ton code est aligné **v5**. + +**BEP-20 vs ERC20 dans le dépôt.** Tu importes le symbole Solidity **`ERC20`**. Sur BSC, l’explorateur et la doc parlent **BEP-20** pour le même comportement. Ce n’est pas un second fichier `BEP20.sol` à écrire. + +**Où voir tout le code OZ en correction ?** `deployment/FGC42Forge_flat.sol` (résultat de `hardhat flatten`) contient FGC42Forge + ERC20 + Ownable + dépendances, dans l’ordre, pour BscScan. + --- ### Hardhat 3 — dossier `code/` @@ -442,7 +502,9 @@ Les fichiers `.ts` ne sont pas déployés. ### OpenZeppelin -Paquet npm `@openzeppelin/contracts` version 5. Le chemin d’import est `@openzeppelin/contracts/token/ERC20/ERC20.sol`. Tu hérites de `ERC20` et de `Ownable`. Tu ne modifies pas les fichiers dans `node_modules`. Si tu changeais de version majeure, il faudrait relire le constructeur : en v5, `Ownable` prend l’owner initial en argument, ce que ton code fait avec `Ownable(msg.sender)`. +→ **Détail complet** (ERC20, Ownable, tableau des fonctions, v5) : section **6.5**, sous-partie **« Détail OpenZeppelin »**. + +En bref : `@openzeppelin/contracts` v5 ; imports `ERC20` + `Ownable` ; `_mint` une fois au constructeur ; pas de `mint` public. ### Hardhat Ignition