verificationdemook
This commit is contained in:
@@ -19,8 +19,8 @@
|
||||
| **1** | [etapes/etape-01-cadrage-wallet-testnet.md](etapes/etape-01-cadrage-wallet-testnet.md) | Décisions token + BSC testnet + tBNB | ✅ **Validée** (0,1 tBNB Telegram) |
|
||||
| **2** | [etapes/etape-02-init-hardhat.md](etapes/etape-02-init-hardhat.md) | Init Hardhat dans `tokenizerRendu/code/` | ✅ |
|
||||
| **3** | *(contrat + tests)* | `FGC42Forge.sol` + tests Mocha | ✅ |
|
||||
| **4** | [etapes/etape-04-deploy-testnet.md](etapes/etape-04-deploy-testnet.md) | Dossier `deployment/` + deploy + BscScan | 🔄 **En cours** |
|
||||
| **5** | *(à venir)* | `documentation/` utilisateur + README école (choix, adresse) | ⏳ |
|
||||
| **4** | [etapes/etape-04-deploy-testnet.md](etapes/etape-04-deploy-testnet.md) | Dossier `deployment/` + deploy + BscScan | ✅ |
|
||||
| **5** | `tokenizerRendu/documentation/README.md` | Doc utilisateur + choix techniques README | ✅ |
|
||||
| **6** | *(à venir)* | Démo minimale + préparation code review | ⏳ |
|
||||
| **7** | *(à venir)* | Bonus multisig (optionnel) | ⏳ |
|
||||
|
||||
|
||||
@@ -4,13 +4,15 @@ Projet 42 — création et déploiement d’un **token** sur blockchain publique
|
||||
|
||||
> **Dépôt de rendu école** : ce dossier est la **racine** du dépôt Git Vogosphere. Pas de `docs/` ni de sujet traduit ici.
|
||||
|
||||
**Guide utilisateur (wallet, transfers, sécurité) :** [`documentation/README.md`](documentation/README.md)
|
||||
|
||||
## État du projet
|
||||
|
||||
| Élément | Statut |
|
||||
|---------|--------|
|
||||
| Smart contract (`code/`) | **FGC42Forge** + tests Hardhat |
|
||||
| Déploiement (`deployment/`) | **Testnet** — voir [`deployment/addresses.json`](deployment/addresses.json) |
|
||||
| Documentation utilisateur (`documentation/`) | À compléter |
|
||||
| Documentation utilisateur (`documentation/`) | **Rédigée** — [`documentation/README.md`](documentation/README.md) |
|
||||
|
||||
## Token
|
||||
|
||||
@@ -20,19 +22,26 @@ Projet 42 — création et déploiement d’un **token** sur blockchain publique
|
||||
| **Symbole** | `FG42` |
|
||||
| **Standard** | **BEP-20** (BNB Smart Chain) — contrat Solidity via OpenZeppelin **`ERC20`** (même interface EVM ; BscScan affiche BEP-20 après deploy) |
|
||||
| **Réseau** | BNB Smart Chain **Testnet**, chainId `97` |
|
||||
| **Supply** | 1 000 000 FG42 (18 décimales) — émission **unique** au deploy, **pas de mint** public ensuite |
|
||||
| **Adresse du contrat** | `0x0c76df26A1149fDc22C8f994975705271b070fF4` |
|
||||
| **Explorer** | https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4 |
|
||||
| **Explorer (contrat)** | https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4 |
|
||||
| **Explorer (token)** | https://testnet.bscscan.com/token/0x0c76df26A1149fDc22C8f994975705271b070fF4 |
|
||||
| **Deployer** | `0xB6bE1878BfaF1FFC8503E752b1D733Ad7b93603c` (`FGC_account`) |
|
||||
| **Source vérifiée (BscScan)** | Oui — détails : [`deployment/BSCSCAN_VERIFICATION.md`](deployment/BSCSCAN_VERIFICATION.md) |
|
||||
|
||||
## Choix techniques (à rédiger pour la soutenance)
|
||||
## Choix techniques
|
||||
|
||||
Explique **pourquoi** tu as fait ces choix (le sujet l’exige) :
|
||||
Résumé pour la soutenance (le sujet demande d’expliquer **pourquoi**) :
|
||||
|
||||
1. **Chaîne** : …
|
||||
2. **Langage / outils** (Solidity, Hardhat, Remix, etc.) : …
|
||||
3. **Bibliothèques** (ex. OpenZeppelin) : …
|
||||
4. **Modèle économique** (supply, mint, decimals) : …
|
||||
5. **Sécurité** (ownership, privilèges, ce qui est interdit) : …
|
||||
1. **Chaîne — BNB Smart Chain Testnet (97)** : blockchain publique EVM alignée avec le partenaire BNB du sujet ; gas en **tBNB** via faucet ; preuve sur **BscScan** testnet sans argent réel.
|
||||
|
||||
2. **Langage / outils — Solidity + Hardhat 3** : langage attendu pour les smart contracts BSC ; Hardhat pour compiler, tester (Mocha/ethers) et déployer (Ignition) de façon reproductible dans `code/` et `deployment/`.
|
||||
|
||||
3. **Bibliothèques — OpenZeppelin `ERC20` + `Ownable`** : implémentation éprouvée du standard fongible ; sur BSC le jeton est qualifié **BEP-20** à l’explorer. Pas de réécriture manuelle de `transfer` / `balanceOf`.
|
||||
|
||||
4. **Modèle économique** : **1 000 000** FG42, **18** décimales ; toute la supply mintée **une fois** au déployeur dans le constructeur ; **aucune** fonction `mint` publique → offre non diluable.
|
||||
|
||||
5. **Sécurité** : compte de test dédié ; secrets dans `.env` local uniquement ; `owner` pour l’admin OpenZeppelin sans création de jetons supplémentaires ; pas de burn. Détail utilisateur : [`documentation/README.md`](documentation/README.md#4-sécurité-et-gouvernance).
|
||||
|
||||
## Structure du dépôt
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expect } from "chai";
|
||||
import { network } from "hardhat";
|
||||
import { expect } from "chai"; // pour les assertions
|
||||
import { network } from "hardhat"; // pour les tests
|
||||
|
||||
const { ethers } = await network.create();
|
||||
|
||||
|
||||
48
tokenizerRendu/deployment/BSCSCAN_VERIFICATION.md
Normal file
48
tokenizerRendu/deployment/BSCSCAN_VERIFICATION.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Vérification du contrat sur BscScan (testnet)
|
||||
|
||||
Fiche **correction / soutenance** : paramètres utilisés pour publier le source et prouver que le bytecode on-chain correspond au dépôt.
|
||||
|
||||
## Statut
|
||||
|
||||
| Champ | Valeur |
|
||||
|-------|--------|
|
||||
| **Vérifié** | Oui (2026-10-20) |
|
||||
| **Contrat** | `FGC42Forge` |
|
||||
| **Adresse** | `0x0c76df26A1149fDc22C8f994975705271b070fF4` |
|
||||
| **Réseau** | BNB Smart Chain Testnet (chainId `97`) |
|
||||
|
||||
## Transaction de création (deploy)
|
||||
|
||||
| Champ | Valeur |
|
||||
|-------|--------|
|
||||
| **Tx hash** | `0xb6a0ec09d4db0e9f0686aca6ad5d8ca71cecaf8d43405eeed214736bb8574072` |
|
||||
| **Lien** | https://testnet.bscscan.com/tx/0xb6a0ec09d4db0e9f0686aca6ad5d8ca71cecaf8d43405eeed214736bb8574072 |
|
||||
| **Bloc** | `137872368` |
|
||||
| **Deployer** | `0xB6bE1878BfaF1FFC8503E752b1D733Ad7b93603c` |
|
||||
|
||||
## Paramètres BscScan « Verify & Publish » (succès)
|
||||
|
||||
| Paramètre | Valeur retenue |
|
||||
|-----------|----------------|
|
||||
| **Méthode** | Solidity (**Single file**) |
|
||||
| **Fichier source collé** | [`FGC42Forge_flat.sol`](FGC42Forge_flat.sol) (généré via `npx hardhat flatten contracts/FGC42Forge.sol`) |
|
||||
| **Nom du contrat** | `FGC42Forge` |
|
||||
| **Compilateur (liste BscScan)** | `v0.8.24+commit.89d56535` *(valeur affichée par BscScan après vérif réussie)* |
|
||||
| **Optimisation** | **Activée** (`Yes` / `1`) |
|
||||
| **Optimizer runs** | `200` |
|
||||
| **Licence** | MIT |
|
||||
| **Arguments du constructeur** | *(vide)* |
|
||||
|
||||
> **Note dev :** le projet compile en local avec **Solidity 0.8.34** (Hardhat 3). Pour la vérification, BscScan a accepté la combinaison **single file aplati + optimizer 200**. En cas de nouvelle tentative, aligner **optimization Yes / 200** ; si échec « bytecode mismatch », essayer **Standard JSON Input** depuis `code/ignition/deployments/chain-97/build-info/solc-0_8_34-….json`.
|
||||
|
||||
## Liens à montrer en évaluation
|
||||
|
||||
- Contrat vérifié : https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4#code
|
||||
- Token FG42 : https://testnet.bscscan.com/token/0x0c76df26A1149fDc22C8f994975705271b070fF4
|
||||
|
||||
## Régénérer le fichier aplati
|
||||
|
||||
```bash
|
||||
cd tokenizerRendu/code
|
||||
npx hardhat flatten contracts/FGC42Forge.sol > ../deployment/FGC42Forge_flat.sol
|
||||
```
|
||||
740
tokenizerRendu/deployment/FGC42Forge_flat.sol
Normal file
740
tokenizerRendu/deployment/FGC42Forge_flat.sol
Normal file
@@ -0,0 +1,740 @@
|
||||
// Sources flattened with hardhat v3.20.0 https://hardhat.org
|
||||
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// File npm/@openzeppelin/contracts@5.6.1/utils/Context.sol
|
||||
|
||||
// Original license: SPDX_License_Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
|
||||
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
/**
|
||||
* @dev Provides information about the current execution context, including the
|
||||
* sender of the transaction and its data. While these are generally available
|
||||
* via msg.sender and msg.data, they should not be accessed in such a direct
|
||||
* manner, since when dealing with meta-transactions the account sending and
|
||||
* paying for execution may not be the actual sender (as far as an application
|
||||
* is concerned).
|
||||
*
|
||||
* This contract is only required for intermediate, library-like contracts.
|
||||
*/
|
||||
abstract contract Context {
|
||||
function _msgSender() internal view virtual returns (address) {
|
||||
return msg.sender;
|
||||
}
|
||||
|
||||
function _msgData() internal view virtual returns (bytes calldata) {
|
||||
return msg.data;
|
||||
}
|
||||
|
||||
function _contextSuffixLength() internal view virtual returns (uint256) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// File npm/@openzeppelin/contracts@5.6.1/access/Ownable.sol
|
||||
|
||||
// Original license: SPDX_License_Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
|
||||
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
/**
|
||||
* @dev Contract module which provides a basic access control mechanism, where
|
||||
* there is an account (an owner) that can be granted exclusive access to
|
||||
* specific functions.
|
||||
*
|
||||
* The initial owner is set to the address provided by the deployer. This can
|
||||
* later be changed with {transferOwnership}.
|
||||
*
|
||||
* This module is used through inheritance. It will make available the modifier
|
||||
* `onlyOwner`, which can be applied to your functions to restrict their use to
|
||||
* the owner.
|
||||
*/
|
||||
abstract contract Ownable is Context {
|
||||
address private _owner;
|
||||
|
||||
/**
|
||||
* @dev The caller account is not authorized to perform an operation.
|
||||
*/
|
||||
error OwnableUnauthorizedAccount(address account);
|
||||
|
||||
/**
|
||||
* @dev The owner is not a valid owner account. (eg. `address(0)`)
|
||||
*/
|
||||
error OwnableInvalidOwner(address owner);
|
||||
|
||||
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
|
||||
|
||||
/**
|
||||
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
|
||||
*/
|
||||
constructor(address initialOwner) {
|
||||
if (initialOwner == address(0)) {
|
||||
revert OwnableInvalidOwner(address(0));
|
||||
}
|
||||
_transferOwnership(initialOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Throws if called by any account other than the owner.
|
||||
*/
|
||||
modifier onlyOwner() {
|
||||
_checkOwner();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the current owner.
|
||||
*/
|
||||
function owner() public view virtual returns (address) {
|
||||
return _owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Throws if the sender is not the owner.
|
||||
*/
|
||||
function _checkOwner() internal view virtual {
|
||||
if (owner() != _msgSender()) {
|
||||
revert OwnableUnauthorizedAccount(_msgSender());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Leaves the contract without owner. It will not be possible to call
|
||||
* `onlyOwner` functions. Can only be called by the current owner.
|
||||
*
|
||||
* NOTE: Renouncing ownership will leave the contract without an owner,
|
||||
* thereby disabling any functionality that is only available to the owner.
|
||||
*/
|
||||
function renounceOwnership() public virtual onlyOwner {
|
||||
_transferOwnership(address(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers ownership of the contract to a new account (`newOwner`).
|
||||
* Can only be called by the current owner.
|
||||
*/
|
||||
function transferOwnership(address newOwner) public virtual onlyOwner {
|
||||
if (newOwner == address(0)) {
|
||||
revert OwnableInvalidOwner(address(0));
|
||||
}
|
||||
_transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers ownership of the contract to a new account (`newOwner`).
|
||||
* Internal function without access restriction.
|
||||
*/
|
||||
function _transferOwnership(address newOwner) internal virtual {
|
||||
address oldOwner = _owner;
|
||||
_owner = newOwner;
|
||||
emit OwnershipTransferred(oldOwner, newOwner);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// File npm/@openzeppelin/contracts@5.6.1/interfaces/draft-IERC6093.sol
|
||||
|
||||
// Original license: SPDX_License_Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v5.5.0) (interfaces/draft-IERC6093.sol)
|
||||
|
||||
pragma solidity >=0.8.4;
|
||||
|
||||
/**
|
||||
* @dev Standard ERC-20 Errors
|
||||
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
|
||||
*/
|
||||
interface IERC20Errors {
|
||||
/**
|
||||
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
|
||||
* @param sender Address whose tokens are being transferred.
|
||||
* @param balance Current balance for the interacting account.
|
||||
* @param needed Minimum amount required to perform a transfer.
|
||||
*/
|
||||
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the token `sender`. Used in transfers.
|
||||
* @param sender Address whose tokens are being transferred.
|
||||
*/
|
||||
error ERC20InvalidSender(address sender);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the token `receiver`. Used in transfers.
|
||||
* @param receiver Address to which tokens are being transferred.
|
||||
*/
|
||||
error ERC20InvalidReceiver(address receiver);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
|
||||
* @param spender Address that may be allowed to operate on tokens without being their owner.
|
||||
* @param allowance Amount of tokens a `spender` is allowed to operate with.
|
||||
* @param needed Minimum amount required to perform a transfer.
|
||||
*/
|
||||
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
|
||||
* @param approver Address initiating an approval operation.
|
||||
*/
|
||||
error ERC20InvalidApprover(address approver);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
|
||||
* @param spender Address that may be allowed to operate on tokens without being their owner.
|
||||
*/
|
||||
error ERC20InvalidSpender(address spender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Standard ERC-721 Errors
|
||||
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
|
||||
*/
|
||||
interface IERC721Errors {
|
||||
/**
|
||||
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-721.
|
||||
* Used in balance queries.
|
||||
* @param owner Address of the current owner of a token.
|
||||
*/
|
||||
error ERC721InvalidOwner(address owner);
|
||||
|
||||
/**
|
||||
* @dev Indicates a `tokenId` whose `owner` is the zero address.
|
||||
* @param tokenId Identifier number of a token.
|
||||
*/
|
||||
error ERC721NonexistentToken(uint256 tokenId);
|
||||
|
||||
/**
|
||||
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
|
||||
* @param sender Address whose tokens are being transferred.
|
||||
* @param tokenId Identifier number of a token.
|
||||
* @param owner Address of the current owner of a token.
|
||||
*/
|
||||
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the token `sender`. Used in transfers.
|
||||
* @param sender Address whose tokens are being transferred.
|
||||
*/
|
||||
error ERC721InvalidSender(address sender);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the token `receiver`. Used in transfers.
|
||||
* @param receiver Address to which tokens are being transferred.
|
||||
*/
|
||||
error ERC721InvalidReceiver(address receiver);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
|
||||
* @param operator Address that may be allowed to operate on tokens without being their owner.
|
||||
* @param tokenId Identifier number of a token.
|
||||
*/
|
||||
error ERC721InsufficientApproval(address operator, uint256 tokenId);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
|
||||
* @param approver Address initiating an approval operation.
|
||||
*/
|
||||
error ERC721InvalidApprover(address approver);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
|
||||
* @param operator Address that may be allowed to operate on tokens without being their owner.
|
||||
*/
|
||||
error ERC721InvalidOperator(address operator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Standard ERC-1155 Errors
|
||||
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
|
||||
*/
|
||||
interface IERC1155Errors {
|
||||
/**
|
||||
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
|
||||
* @param sender Address whose tokens are being transferred.
|
||||
* @param balance Current balance for the interacting account.
|
||||
* @param needed Minimum amount required to perform a transfer.
|
||||
* @param tokenId Identifier number of a token.
|
||||
*/
|
||||
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the token `sender`. Used in transfers.
|
||||
* @param sender Address whose tokens are being transferred.
|
||||
*/
|
||||
error ERC1155InvalidSender(address sender);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the token `receiver`. Used in transfers.
|
||||
* @param receiver Address to which tokens are being transferred.
|
||||
*/
|
||||
error ERC1155InvalidReceiver(address receiver);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
|
||||
* @param operator Address that may be allowed to operate on tokens without being their owner.
|
||||
* @param owner Address of the current owner of a token.
|
||||
*/
|
||||
error ERC1155MissingApprovalForAll(address operator, address owner);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
|
||||
* @param approver Address initiating an approval operation.
|
||||
*/
|
||||
error ERC1155InvalidApprover(address approver);
|
||||
|
||||
/**
|
||||
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
|
||||
* @param operator Address that may be allowed to operate on tokens without being their owner.
|
||||
*/
|
||||
error ERC1155InvalidOperator(address operator);
|
||||
|
||||
/**
|
||||
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
|
||||
* Used in batch transfers.
|
||||
* @param idsLength Length of the array of token identifiers
|
||||
* @param valuesLength Length of the array of token amounts
|
||||
*/
|
||||
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
|
||||
}
|
||||
|
||||
|
||||
// File npm/@openzeppelin/contracts@5.6.1/token/ERC20/IERC20.sol
|
||||
|
||||
// Original license: SPDX_License_Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
|
||||
|
||||
pragma solidity >=0.4.16;
|
||||
|
||||
/**
|
||||
* @dev Interface of the ERC-20 standard as defined in the ERC.
|
||||
*/
|
||||
interface IERC20 {
|
||||
/**
|
||||
* @dev Emitted when `value` tokens are moved from one account (`from`) to
|
||||
* another (`to`).
|
||||
*
|
||||
* Note that `value` may be zero.
|
||||
*/
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
|
||||
* a call to {approve}. `value` is the new allowance.
|
||||
*/
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
|
||||
/**
|
||||
* @dev Returns the value of tokens in existence.
|
||||
*/
|
||||
function totalSupply() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the value of tokens owned by `account`.
|
||||
*/
|
||||
function balanceOf(address account) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*/
|
||||
function transfer(address to, uint256 value) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Returns the remaining number of tokens that `spender` will be
|
||||
* allowed to spend on behalf of `owner` through {transferFrom}. This is
|
||||
* zero by default.
|
||||
*
|
||||
* This value changes when {approve} or {transferFrom} are called.
|
||||
*/
|
||||
function allowance(address owner, address spender) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
|
||||
* caller's tokens.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* IMPORTANT: Beware that changing an allowance with this method brings the risk
|
||||
* that someone may use both the old and the new allowance by unfortunate
|
||||
* transaction ordering. One possible solution to mitigate this race
|
||||
* condition is to first reduce the spender's allowance to 0 and set the
|
||||
* desired value afterwards:
|
||||
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
|
||||
*
|
||||
* Emits an {Approval} event.
|
||||
*/
|
||||
function approve(address spender, uint256 value) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Moves a `value` amount of tokens from `from` to `to` using the
|
||||
* allowance mechanism. `value` is then deducted from the caller's
|
||||
* allowance.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*/
|
||||
function transferFrom(address from, address to, uint256 value) external returns (bool);
|
||||
}
|
||||
|
||||
|
||||
// File npm/@openzeppelin/contracts@5.6.1/token/ERC20/extensions/IERC20Metadata.sol
|
||||
|
||||
// Original license: SPDX_License_Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)
|
||||
|
||||
pragma solidity >=0.6.2;
|
||||
|
||||
/**
|
||||
* @dev Interface for the optional metadata functions from the ERC-20 standard.
|
||||
*/
|
||||
interface IERC20Metadata is IERC20 {
|
||||
/**
|
||||
* @dev Returns the name of the token.
|
||||
*/
|
||||
function name() external view returns (string memory);
|
||||
|
||||
/**
|
||||
* @dev Returns the symbol of the token.
|
||||
*/
|
||||
function symbol() external view returns (string memory);
|
||||
|
||||
/**
|
||||
* @dev Returns the decimals places of the token.
|
||||
*/
|
||||
function decimals() external view returns (uint8);
|
||||
}
|
||||
|
||||
|
||||
// File npm/@openzeppelin/contracts@5.6.1/token/ERC20/ERC20.sol
|
||||
|
||||
// Original license: SPDX_License_Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/ERC20.sol)
|
||||
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @dev Implementation of the {IERC20} interface.
|
||||
*
|
||||
* This implementation is agnostic to the way tokens are created. This means
|
||||
* that a supply mechanism has to be added in a derived contract using {_mint}.
|
||||
*
|
||||
* TIP: For a detailed writeup see our guide
|
||||
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
|
||||
* to implement supply mechanisms].
|
||||
*
|
||||
* The default value of {decimals} is 18. To change this, you should override
|
||||
* this function so it returns a different value.
|
||||
*
|
||||
* We have followed general OpenZeppelin Contracts guidelines: functions revert
|
||||
* instead returning `false` on failure. This behavior is nonetheless
|
||||
* conventional and does not conflict with the expectations of ERC-20
|
||||
* applications.
|
||||
*/
|
||||
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
|
||||
mapping(address account => uint256) private _balances;
|
||||
|
||||
mapping(address account => mapping(address spender => uint256)) private _allowances;
|
||||
|
||||
uint256 private _totalSupply;
|
||||
|
||||
string private _name;
|
||||
string private _symbol;
|
||||
|
||||
/**
|
||||
* @dev Sets the values for {name} and {symbol}.
|
||||
*
|
||||
* Both values are immutable: they can only be set once during construction.
|
||||
*/
|
||||
constructor(string memory name_, string memory symbol_) {
|
||||
_name = name_;
|
||||
_symbol = symbol_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the name of the token.
|
||||
*/
|
||||
function name() public view virtual returns (string memory) {
|
||||
return _name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the symbol of the token, usually a shorter version of the
|
||||
* name.
|
||||
*/
|
||||
function symbol() public view virtual returns (string memory) {
|
||||
return _symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the number of decimals used to get its user representation.
|
||||
* For example, if `decimals` equals `2`, a balance of `505` tokens should
|
||||
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
|
||||
*
|
||||
* Tokens usually opt for a value of 18, imitating the relationship between
|
||||
* Ether and Wei. This is the default value returned by this function, unless
|
||||
* it's overridden.
|
||||
*
|
||||
* NOTE: This information is only used for _display_ purposes: it in
|
||||
* no way affects any of the arithmetic of the contract, including
|
||||
* {IERC20-balanceOf} and {IERC20-transfer}.
|
||||
*/
|
||||
function decimals() public view virtual returns (uint8) {
|
||||
return 18;
|
||||
}
|
||||
|
||||
/// @inheritdoc IERC20
|
||||
function totalSupply() public view virtual returns (uint256) {
|
||||
return _totalSupply;
|
||||
}
|
||||
|
||||
/// @inheritdoc IERC20
|
||||
function balanceOf(address account) public view virtual returns (uint256) {
|
||||
return _balances[account];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-transfer}.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `to` cannot be the zero address.
|
||||
* - the caller must have a balance of at least `value`.
|
||||
*/
|
||||
function transfer(address to, uint256 value) public virtual returns (bool) {
|
||||
address owner = _msgSender();
|
||||
_transfer(owner, to, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @inheritdoc IERC20
|
||||
function allowance(address owner, address spender) public view virtual returns (uint256) {
|
||||
return _allowances[owner][spender];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-approve}.
|
||||
*
|
||||
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
|
||||
* `transferFrom`. This is semantically equivalent to an infinite approval.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `spender` cannot be the zero address.
|
||||
*/
|
||||
function approve(address spender, uint256 value) public virtual returns (bool) {
|
||||
address owner = _msgSender();
|
||||
_approve(owner, spender, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-transferFrom}.
|
||||
*
|
||||
* Skips emitting an {Approval} event indicating an allowance update. This is not
|
||||
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
|
||||
*
|
||||
* NOTE: Does not update the allowance if the current allowance
|
||||
* is the maximum `uint256`.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `from` and `to` cannot be the zero address.
|
||||
* - `from` must have a balance of at least `value`.
|
||||
* - the caller must have allowance for ``from``'s tokens of at least
|
||||
* `value`.
|
||||
*/
|
||||
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
|
||||
address spender = _msgSender();
|
||||
_spendAllowance(from, spender, value);
|
||||
_transfer(from, to, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Moves a `value` amount of tokens from `from` to `to`.
|
||||
*
|
||||
* This internal function is equivalent to {transfer}, and can be used to
|
||||
* e.g. implement automatic token fees, slashing mechanisms, etc.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*
|
||||
* NOTE: This function is not virtual, {_update} should be overridden instead.
|
||||
*/
|
||||
function _transfer(address from, address to, uint256 value) internal {
|
||||
if (from == address(0)) {
|
||||
revert ERC20InvalidSender(address(0));
|
||||
}
|
||||
if (to == address(0)) {
|
||||
revert ERC20InvalidReceiver(address(0));
|
||||
}
|
||||
_update(from, to, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
|
||||
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
|
||||
* this function.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*/
|
||||
function _update(address from, address to, uint256 value) internal virtual {
|
||||
if (from == address(0)) {
|
||||
// Overflow check required: The rest of the code assumes that totalSupply never overflows
|
||||
_totalSupply += value;
|
||||
} else {
|
||||
uint256 fromBalance = _balances[from];
|
||||
if (fromBalance < value) {
|
||||
revert ERC20InsufficientBalance(from, fromBalance, value);
|
||||
}
|
||||
unchecked {
|
||||
// Overflow not possible: value <= fromBalance <= totalSupply.
|
||||
_balances[from] = fromBalance - value;
|
||||
}
|
||||
}
|
||||
|
||||
if (to == address(0)) {
|
||||
unchecked {
|
||||
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
|
||||
_totalSupply -= value;
|
||||
}
|
||||
} else {
|
||||
unchecked {
|
||||
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
|
||||
_balances[to] += value;
|
||||
}
|
||||
}
|
||||
|
||||
emit Transfer(from, to, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
|
||||
* Relies on the `_update` mechanism
|
||||
*
|
||||
* Emits a {Transfer} event with `from` set to the zero address.
|
||||
*
|
||||
* NOTE: This function is not virtual, {_update} should be overridden instead.
|
||||
*/
|
||||
function _mint(address account, uint256 value) internal {
|
||||
if (account == address(0)) {
|
||||
revert ERC20InvalidReceiver(address(0));
|
||||
}
|
||||
_update(address(0), account, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
|
||||
* Relies on the `_update` mechanism.
|
||||
*
|
||||
* Emits a {Transfer} event with `to` set to the zero address.
|
||||
*
|
||||
* NOTE: This function is not virtual, {_update} should be overridden instead
|
||||
*/
|
||||
function _burn(address account, uint256 value) internal {
|
||||
if (account == address(0)) {
|
||||
revert ERC20InvalidSender(address(0));
|
||||
}
|
||||
_update(account, address(0), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
|
||||
*
|
||||
* This internal function is equivalent to `approve`, and can be used to
|
||||
* e.g. set automatic allowances for certain subsystems, etc.
|
||||
*
|
||||
* Emits an {Approval} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `owner` cannot be the zero address.
|
||||
* - `spender` cannot be the zero address.
|
||||
*
|
||||
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
|
||||
*/
|
||||
function _approve(address owner, address spender, uint256 value) internal {
|
||||
_approve(owner, spender, value, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
|
||||
*
|
||||
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
|
||||
* `_spendAllowance` during the `transferFrom` operation sets the flag to false. This saves gas by not emitting any
|
||||
* `Approval` event during `transferFrom` operations.
|
||||
*
|
||||
* Anyone who wishes to continue emitting `Approval` events on the `transferFrom` operation can force the flag to
|
||||
* true using the following override:
|
||||
*
|
||||
* ```solidity
|
||||
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
|
||||
* super._approve(owner, spender, value, true);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Requirements are the same as {_approve}.
|
||||
*/
|
||||
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
|
||||
if (owner == address(0)) {
|
||||
revert ERC20InvalidApprover(address(0));
|
||||
}
|
||||
if (spender == address(0)) {
|
||||
revert ERC20InvalidSpender(address(0));
|
||||
}
|
||||
_allowances[owner][spender] = value;
|
||||
if (emitEvent) {
|
||||
emit Approval(owner, spender, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates `owner`'s allowance for `spender` based on spent `value`.
|
||||
*
|
||||
* Does not update the allowance value in case of infinite allowance.
|
||||
* Revert if not enough allowance is available.
|
||||
*
|
||||
* Does not emit an {Approval} event.
|
||||
*/
|
||||
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
|
||||
uint256 currentAllowance = allowance(owner, spender);
|
||||
if (currentAllowance < type(uint256).max) {
|
||||
if (currentAllowance < value) {
|
||||
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
|
||||
}
|
||||
unchecked {
|
||||
_approve(owner, spender, currentAllowance - value, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// File contracts/FGC42Forge.sol
|
||||
|
||||
// Original license: SPDX_License_Identifier: MIT
|
||||
pragma solidity ^0.8.34;
|
||||
|
||||
|
||||
/// @title FGC42Forge — jeton fongible pour BNB Smart Chain Testnet
|
||||
/// @notice Standard **BEP-20** (exigé sur BSC) : même interface que l’ERC-20 sur l’EVM.
|
||||
/// On importe OpenZeppelin `ERC20` ; après déploiement sur BSC, BscScan affiche un token BEP-20.
|
||||
/// Phrase soutenance : « BEP-20 sur la chaîne, implémenté via ERC20 OpenZeppelin. »
|
||||
contract FGC42Forge is ERC20, Ownable {
|
||||
uint256 private constant INITIAL_SUPPLY = 1_000_000 * (10 ** 18);
|
||||
|
||||
constructor() ERC20("FGC42Forge", "FG42") Ownable(msg.sender) {
|
||||
_mint(msg.sender, INITIAL_SUPPLY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,3 +40,10 @@ Hardhat peut afficher une estimation de gas et demander une confirmation.
|
||||
## Module Ignition
|
||||
|
||||
Source : [`code/ignition/modules/FGC42Forge.ts`](../code/ignition/modules/FGC42Forge.ts)
|
||||
|
||||
## Vérification BscScan
|
||||
|
||||
Contrat **vérifié** sur testnet. Paramètres et liens pour la soutenance :
|
||||
|
||||
→ [`BSCSCAN_VERIFICATION.md`](BSCSCAN_VERIFICATION.md)
|
||||
→ Source aplati : [`FGC42Forge_flat.sol`](FGC42Forge_flat.sol)
|
||||
|
||||
@@ -7,5 +7,10 @@
|
||||
"address": "0x0c76df26A1149fDc22C8f994975705271b070fF4",
|
||||
"deployedAt": "2026-10-20",
|
||||
"deployer": "0xB6bE1878BfaF1FFC8503E752b1D733Ad7b93603c",
|
||||
"explorer": "https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4"
|
||||
"explorer": "https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4",
|
||||
"creationTx": "0xb6a0ec09d4db0e9f0686aca6ad5d8ca71cecaf8d43405eeed214736bb8574072",
|
||||
"creationBlock": 137872368,
|
||||
"bscscanVerified": true,
|
||||
"bscscanVerifiedAt": "2026-10-20",
|
||||
"bscscanVerificationDoc": "deployment/BSCSCAN_VERIFICATION.md"
|
||||
}
|
||||
|
||||
@@ -1,13 +1,121 @@
|
||||
# Documentation du token
|
||||
# Documentation utilisateur — FGC42Forge (FG42)
|
||||
|
||||
Ce dossier est évalué en soutenance : il doit permettre de **comprendre** le token et de **l’utiliser** (wallet, transferts, rôle du token).
|
||||
Ce document permet de **comprendre** le token et de **l’utiliser** (wallet, transferts) sans lire le code Solidity.
|
||||
|
||||
## Contenu à rédiger
|
||||
> Documentation **évaluateur** : distincte du dossier `code/` (développement) et du dépôt de travail perso `docs/`.
|
||||
|
||||
1. **Présentation** — à quoi sert ce token (même dans un cadre pédagogique).
|
||||
2. **Réseau et adresse** — lien vers l’explorer.
|
||||
3. **Guide d’utilisation** — ajouter le token dans un wallet, effectuer un transfert.
|
||||
4. **Sécurité et gouvernance** — owner, mint, limites connues.
|
||||
5. **(Optionnel)** `WHITEPAPER.md` — vision et fonctionnalités sur 1–2 pages.
|
||||
---
|
||||
|
||||
Ce fichier est distinct de la documentation **dev** du dépôt perso (`docs/` à la racine du dépôt de travail).
|
||||
## 1. Présentation
|
||||
|
||||
**FGC42Forge** est un jeton **BEP-20** déployé sur **BNB Smart Chain Testnet** dans le cadre du projet 42 *Tokenizer*.
|
||||
|
||||
| Élément | Valeur |
|
||||
|---------|--------|
|
||||
| **Nom** | FGC42Forge |
|
||||
| **Symbole** | FG42 |
|
||||
| **Standard** | BEP-20 (interface équivalente à l’ERC-20 sur l’EVM) |
|
||||
| **Décimales** | 18 |
|
||||
| **Offre totale** | 1 000 000 FG42 |
|
||||
|
||||
**Rôle :** token de démonstration (tests, déploiement, wallet, explorateur de blocs).
|
||||
|
||||
**Valeur :** aucune valeur monétaire réelle ; réseau de **test** uniquement. Le gas se paie en **tBNB**.
|
||||
|
||||
**Offre et création de jetons :** les 1 000 000 FG42 ont été émis **une seule fois** lors du déploiement du contrat. Il n’existe **aucune fonction publique** pour en créer davantage après coup (*pas de mint*). Seuls les **transferts** entre comptes déplacent des FG42 déjà existants ; l’offre totale on-chain ne augmente pas.
|
||||
|
||||
*FGC* : initiales du créateur du projet · **42** : contrainte du sujet · *Forge* : métaphore de la création du jeton au moment du deploy.
|
||||
|
||||
---
|
||||
|
||||
## 2. Réseau et adresse
|
||||
|
||||
| Paramètre | Valeur |
|
||||
|-----------|--------|
|
||||
| **Réseau** | BNB Smart Chain **Testnet** |
|
||||
| **Chain ID** | `97` |
|
||||
| **Monnaie gas** | tBNB |
|
||||
| **Adresse du contrat** | `0x0c76df26A1149fDc22C8f994975705271b070fF4` |
|
||||
|
||||
**Liens utiles :**
|
||||
|
||||
- Page **contrat** : https://testnet.bscscan.com/address/0x0c76df26A1149fDc22C8f994975705271b070fF4
|
||||
- Page **token** (supply, holders, transfers) : https://testnet.bscscan.com/token/0x0c76df26A1149fDc22C8f994975705271b070fF4
|
||||
|
||||
Données structurées du déploiement : [`../deployment/addresses.json`](../deployment/addresses.json).
|
||||
|
||||
### Contrat vérifié sur BscScan
|
||||
|
||||
Le **code source** est publié sur l’explorateur (onglet **Contract** → code lisible). Utile en correction pour prouver que le déployé correspond au dépôt Git.
|
||||
|
||||
| Élément | Détail |
|
||||
|---------|--------|
|
||||
| **Statut** | Vérifié (2026-10-20) |
|
||||
| **Tx de création** | [`0xb6a0…4072`](https://testnet.bscscan.com/tx/0xb6a0ec09d4db0e9f0686aca6ad5d8ca71cecaf8d43405eeed214736bb8574072) |
|
||||
| **Fiche technique complète** | [`../deployment/BSCSCAN_VERIFICATION.md`](../deployment/BSCSCAN_VERIFICATION.md) (compilateur, optimizer, fichier aplati) |
|
||||
|
||||
### Configurer MetaMask (réseau)
|
||||
|
||||
Si le réseau n’est pas déjà présent :
|
||||
|
||||
| Champ | Valeur |
|
||||
|-------|--------|
|
||||
| Nom du réseau | BNB Smart Chain Testnet |
|
||||
| RPC URL | `https://data-seed-prebsc-1-s1.binance.org:8545/` |
|
||||
| Chain ID | `97` |
|
||||
| Symbole | tBNB |
|
||||
| Explorateur | `https://testnet.bscscan.com` |
|
||||
|
||||
Obtenir du **tBNB** : faucet BNB Chain testnet ou canaux officiels (Telegram @bnbchain_official_bot, etc.).
|
||||
|
||||
---
|
||||
|
||||
## 3. Guide d’utilisation
|
||||
|
||||
### 3.1 Importer FG42 dans MetaMask
|
||||
|
||||
1. Ouvrir MetaMask sur le réseau **BNB Smart Chain Testnet**.
|
||||
2. Menu **Tokens** → **Importer des tokens** (*Import tokens*).
|
||||
3. Coller l’**adresse du contrat** :
|
||||
`0x0c76df26A1149fDc22C8f994975705271b070fF4`
|
||||
4. Le symbole **FG42** et les **18** décimales se remplissent en général automatiquement → confirmer.
|
||||
|
||||
Le compte qui a **déployé** le contrat détient initialement **1 000 000 FG42** (visible après import). Les autres comptes affichent **0** jusqu’à réception d’un transfer.
|
||||
|
||||
### 3.2 Consulter le token sur BscScan
|
||||
|
||||
1. Ouvrir la [page token](https://testnet.bscscan.com/token/0x0c76df26A1149fDc22C8f994975705271b070fF4).
|
||||
2. Vérifier **Max Total Supply** : 1 000 000 FG42.
|
||||
3. Onglet **Transfers** : historique des mouvements BEP-20.
|
||||
|
||||
### 3.3 Effectuer un transfert (MetaMask)
|
||||
|
||||
**Prérequis :** le compte émetteur possède des FG42 et un peu de **tBNB** pour le gas.
|
||||
|
||||
1. MetaMask → actif **FG42** → **Envoyer** (*Send*).
|
||||
2. Adresse du destinataire (autre compte test).
|
||||
3. Montant (ex. `100` FG42) → confirmer la transaction.
|
||||
4. Vérifier sur BscScan (onglet Transfers du token) et dans le wallet du destinataire (importer le token si besoin).
|
||||
|
||||
**Note :** un transfer **ne crée pas** de nouveaux FG42 ; il déplace une partie de l’offre existante.
|
||||
|
||||
---
|
||||
|
||||
## 4. Sécurité et gouvernance
|
||||
|
||||
| Sujet | Comportement de FGC42Forge |
|
||||
|-------|----------------------------|
|
||||
| **Testnet** | Jeton fictif ; ne pas utiliser de fonds mainnet sur les comptes de démo. |
|
||||
| **Supply** | Fixe à **1 000 000 FG42** après le deploy. |
|
||||
| **Mint** | Aucune fonction publique pour augmenter l’offre. |
|
||||
| **Burn** | Non implémenté dans ce contrat. |
|
||||
| **Owner** | Le contrat utilise **OpenZeppelin `Ownable`** : une adresse `owner()` (le déployeur au lancement) peut gérer le rôle admin (ex. `transferOwnership`), mais **sans** pouvoir mint des FG42 supplémentaires via ce contrat. |
|
||||
| **Clés privées** | Ne jamais partager seed phrase ni clé privée ; ne pas les committer dans Git. |
|
||||
|
||||
Pour le modèle technique (Hardhat, OpenZeppelin, choix BSC), voir le [README racine](../README.md#choix-techniques).
|
||||
|
||||
---
|
||||
|
||||
## 5. Whitepaper (optionnel)
|
||||
|
||||
Un document `WHITEPAPER.md` peut compléter cette page (vision, limites, public cible). Non requis si cette documentation reste complète.
|
||||
|
||||
Reference in New Issue
Block a user