SC-24 : Deploiement sur Testnets

# Parameters
BATCH_MODE = "true"

Navigation : Sommaire | << Précédent | Suivant >>


Objectifs d’apprentissage

A la fin de ce notebook, vous saurez : 1. Configurer une connexion Sepolia via Alchemy/Infura 2. Preparer un wallet et obtenir du testnet ETH via faucet 3. Deployer un contrat sur un reseau public (Sepolia) 4. Interagir avec un contrat deploye sur testnet 5. Utiliser xrpl-py pour envoyer des transactions sur le XRP Testnet

Prerequis

Duree estimee : 50 minutes


0. Prerequis

  • Cle API Alchemy ou Infura (gratuit)
  • MetaMask ou wallet Ethereum pour recevoir du testnet ETH
  • Faucet Sepolia : Google Cloud Faucet ou Alchemy Faucet
  • Python : pip install web3 py-solc-x xrpl-py python-dotenv

0.5 Setup prealable

Option A : Créer votre propre wallet (recommande)

  1. Installez MetaMask : https://metamask.io/

  2. Créez un wallet et notez votre phrase de recuperation (ne la partagez jamais)

  3. Passez sur Sepolia : dans MetaMask, cliquez sur le reseaux > “Afficher les reseaux de test” > selectionnez “Sepolia”

  4. Obtenez du Sepolia ETH via un faucet :

  5. Exportez votre cle privee : MetaMask > Details du compte > Exporter la cle privee

  6. Configurez votre .env :

    SEPOLIA_RPC=https://eth-sepolia.g.alchemy.com/v2/VOTRE_CLE_API
    DEPLOYER_PRIVATE_KEY=0xVOTRE_CLE_PRIVEE

Securite : Ces cles sont pour le testnet uniquement. N’utilisez JAMAIS de cles contenant des fonds reels.

Option B : Cle fournie par le professeur

Si le professeur fournit une cle de testnet pre-approvisionnee, ajoutez-la directement dans votre .env. Cette cle ne contient que du Sepolia ETH (valeur nulle).


Transition : Prerequis verifies

Maintenant que l’environnement est configure (RPC, cle privee), nous pouvons nous connecter a Sepolia.

Différence avec anvil : Sepolia est un reseau public avec des temps de bloc reels (~12s), alors qu’anvil est instantane.

Prochaine étape : Etablir la connexion Web3 avec Sepolia.

# Configuration
import os
from pathlib import Path
from dotenv import load_dotenv

# Chercher .env : CWD, puis dossier du notebook, puis SmartContracts parent
_env_path = None
_cwd = Path(os.getcwd()).resolve()

# 1. CWD et ses parents
_search = _cwd
for _ in range(6):
    if (_search / ".env").exists():
        _env_path = _search / ".env"
        break
    _search = _search.parent

# 2. Chercher SmartContracts/.env dans les sous-dossiers du CWD
if not _env_path:
    for p in _cwd.rglob("SmartContracts/.env"):
        _env_path = p
        break

if _env_path:
    load_dotenv(_env_path)
else:
    load_dotenv()

# Sepolia via Alchemy (remplacez par votre cle)
SEPOLIA_RPC = os.getenv("SEPOLIA_RPC", "https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY")
PRIVATE_KEY = os.getenv("DEPLOYER_PRIVATE_KEY", "")  # Cle privee du deployer

# Verification
if "YOUR_KEY" in SEPOLIA_RPC:
    print("ATTENTION: Configurez SEPOLIA_RPC dans votre .env")
    print("  Suivez les instructions 'Setup prealable' ci-dessus")
else:
    print(f"RPC configure: {SEPOLIA_RPC[:40]}...")

if not PRIVATE_KEY:
    print("\nATTENTION: DEPLOYER_PRIVATE_KEY non configure dans .env")
    print("  Les sections deploiement seront ignorees (compile-only)")
ATTENTION: Configurez SEPOLIA_RPC dans votre .env
  Suivez les instructions 'Setup prealable' ci-dessus

ATTENTION: DEPLOYER_PRIVATE_KEY non configure dans .env
  Les sections deploiement seront ignorees (compile-only)

Transition : Configuration et connexion

La configuration charge les variables d’environnement depuis .env. Si tout est correct, le RPC et la cle privee sont disponibles.

Prochaine étape : Se connecter a Sepolia et verifier que la connexion fonctionne.


1. Connexion a Sepolia

Contrairement a anvil (blockchain locale), Sepolia est un reseau public. Les transactions prennent ~12 secondes (temps de bloc reel).

try:
    from web3 import Web3
    import solcx
    WEB3_AVAILABLE = True
except ImportError:
    WEB3_AVAILABLE = False
    print("web3 ou py-solc-x non installe. Installez avec: pip install web3 py-solc-x")

if WEB3_AVAILABLE:
    # Connexion
    w3 = Web3(Web3.HTTPProvider(SEPOLIA_RPC))

    if w3.is_connected():
        chain_id = w3.eth.chain_id
        block = w3.eth.block_number
        print(f"Connecte a Sepolia (chain_id={chain_id})")
        print(f"Bloc actuel: {block:,}")
        print(f"Gas price: {w3.from_wei(w3.eth.gas_price, 'gwei'):.2f} gwei")
    else:
        print("Impossible de se connecter. Verifiez votre cle API.")
else:
    print("Section sautee : web3 non disponible")
Impossible de se connecter. Verifiez votre cle API.

Interpretation : Connexion a Sepolia

Sortie reelle (sans cle API configuree) : Impossible de se connecter. Verifiez votre cle API. Les valeurs du tableau ci-dessous sont celles attendues une fois une cle Alchemy/Infura configuree.

Élément Valeur Signification
Chain ID 11155111 Identifiant unique du reseau Sepolia
Bloc actuel 10,719,401 Dernier bloc finalise
Gas price 0.00 gwei Prix du gas (EIP-1559, peut varier)

Points cles : 1. Sepolia est un reseau public de test pour Ethereum 2. Le bloc actuel augmente toutes les ~12 secondes 3. Le gas price a 0 gwei signifie que les transactions sont quasi-gratuites

Note technique : Alchemy et Infura sont des “node providers” qui donnent acces a un noeud Ethereum sans heberger son propre nœud. L’inscription est gratuite pour un usage limite.


2. Preparation du deployer

Sur un testnet, vous avez besoin d’un compte avec du testnet ETH. Utilisez un faucet pour obtenir du Sepolia ETH gratuitement.

try:
    from eth_account import Account
    ETH_ACCOUNT_AVAILABLE = True
except ImportError:
    ETH_ACCOUNT_AVAILABLE = False

if ETH_ACCOUNT_AVAILABLE and PRIVATE_KEY:
    account = Account.from_key(PRIVATE_KEY)
    balance = w3.eth.get_balance(account.address)
    print(f"Deployer: {account.address}")
    print(f"Balance: {w3.from_wei(balance, 'ether'):.4f} ETH")
    if balance == 0:
        print("\nBalance nulle! Obtenez du Sepolia ETH via un faucet:")
        print(f"  https://cloud.google.com/application/web3/faucet/ethereum/sepolia")
        print(f"  Adresse a alimenter: {account.address}")
else:
    if not ETH_ACCOUNT_AVAILABLE:
        print("eth_account non installe. Installez avec: pip install eth-account")
    else:
        print("Pas de cle privee configuree.")
        print("Pour generer un nouveau wallet de test:")
        print("  account = Account.create()")
        print("  print(account.address, account.key.hex())")
Pas de cle privee configuree.
Pour generer un nouveau wallet de test:
  account = Account.create()
  print(account.address, account.key.hex())

Interpretation : Balance du deployer

Sortie reelle (sans cle privee configuree) : Pas de cle privee configuree. Les valeurs du tableau ci-dessous illustrent ce qui est attendu une fois DEPLOYER_PRIVATE_KEY configuree.

Élément Valeur Signification
Adresse 0x6E3D0... Adresse Ethereum du deployer
Balance 0.0500 ETH Montant disponible pour les transactions
Estimation gas ~0.001 ETH/transaction Cout d’un deploiement simple

Points cles : 1. La balance est en Sepolia ETH (valeur nulle, monnaie de test) 2. Chaque transaction consomme du gas (payable en ETH) 3. Si la balance tombe a 0, il faut utiliser un faucet pour recharger

Note technique : 0.05 ETH de test est suffisant pour des dizaines de deploiements. Sur mainnet, 0.05 ETH reel (~100 USD) serait critique a ne pas gaspiller.


3. Deploiement d’un contrat sur Sepolia

Nous deploierons un contrat SimpleStorage - le même que dans SC-3, mais cette fois sur un vrai reseau public.

SIMPLE_STORAGE = """
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

contract SimpleStorage {
    uint256 public storedValue;
    address public owner;
    
    event ValueChanged(uint256 oldValue, uint256 newValue, address changedBy);
    
    constructor(uint256 _initialValue) {
        storedValue = _initialValue;
        owner = msg.sender;
    }
    
    function set(uint256 _value) external {
        uint256 old = storedValue;
        storedValue = _value;
        emit ValueChanged(old, _value, msg.sender);
    }
    
    function get() external view returns (uint256) {
        return storedValue;
    }
}
"""

if WEB3_AVAILABLE:
    # Compiler
    SOLC_VERSION = "0.8.28"
    installed = [str(v) for v in solcx.get_installed_solc_versions()]
    if SOLC_VERSION not in installed:
        solcx.install_solc(SOLC_VERSION)
    solcx.set_solc_version(SOLC_VERSION)

    compiled = solcx.compile_source(
        SIMPLE_STORAGE, output_values=["abi", "bin"], solc_version=SOLC_VERSION
    )
    contract_id, contract_interface = compiled.popitem()
    print(f"Contrat compile: {contract_id}")
    print(f"Bytecode: {len(contract_interface['bin'])} caracteres")
    print(f"ABI: {len(contract_interface['abi'])} fonctions/events")
else:
    print("Section sautee : web3/solcx non disponible")
Contrat compile: <stdin>:SimpleStorage
Bytecode: 1750 caracteres
ABI: 6 fonctions/events

Interpretation : Compilation du contrat

Sortie obtenue : Contrat SimpleStorage compile avec succes.

Élément Valeur Signification
Bytecode 1750 caractères Code machine deployable sur l’EVM
ABI 6 fonctions/events Interface pour interagir avec le contrat
Version Solidity 0.8.28 Compilateur utilise

Points cles : 1. Le bytecode est ce qui sera stocke sur la blockchain (1750 octets) 2. L’ABI (Application Binary Interface) decrit les fonctions accessibles 3. La compilation est locale (pas de cout, pas de transaction)

Note technique : Le bytecode contient tout le code du contrat. Une fois deploye, il est immutable et ne peut etre modifie. C’est pourquoi les tests sur testnet sont critiques avant le deploiement mainnet.

Déploiement du contrat SimpleStorage sur Sepolia, nécessitant un compte approvisionné en ETH de test.

# Deploiement sur Sepolia (necessite du testnet ETH)
_deployment_ok = True

if not PRIVATE_KEY:
    print("DEPLOYER_PRIVATE_KEY non configure.")
    print("Ajoutez votre cle testnet dans .env (voir section 'Setup prealable')")
    _deployment_ok = False
elif not WEB3_AVAILABLE:
    print("web3 non disponible, deploiement impossible.")
    _deployment_ok = False
elif not w3.is_connected():
    print("Impossible de se connecter a Sepolia. Verifiez SEPOLIA_RPC.")
    _deployment_ok = False

if _deployment_ok:
    Contract = w3.eth.contract(
        abi=contract_interface["abi"],
        bytecode=contract_interface["bin"]
    )

    # Construire la transaction
    nonce = w3.eth.get_transaction_count(account.address)
    tx = Contract.constructor(42).build_transaction({
        "from": account.address,
        "nonce": nonce,
        "gas": 500000,
        "gasPrice": w3.eth.gas_price,
        "chainId": 11155111,  # Sepolia
    })

    # Signer et envoyer
    signed_tx = w3.eth.account.sign_transaction(tx, PRIVATE_KEY)
    tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction)
    print(f"Transaction envoyee: {tx_hash.hex()}")
    print(f"Explorer: https://sepolia.etherscan.io/tx/{tx_hash.hex()}")

    # Attendre confirmation (~12s)
    print("Attente de confirmation...")
    receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120)
    print(f"Deploye a: {receipt.contractAddress}")
    print(f"Gas utilise: {receipt.gasUsed:,}")
    print(f"Explorer: https://sepolia.etherscan.io/address/{receipt.contractAddress}")
DEPLOYER_PRIVATE_KEY non configure.
Ajoutez votre cle testnet dans .env (voir section 'Setup prealable')

Interpretation : Deploiement sur Sepolia

Sortie reelle (sans cle privee configuree) : DEPLOYER_PRIVATE_KEY non configure. Les valeurs du tableau ci-dessous illustrent un deploiement reussi attendu une fois la cle configuree.

Élément Valeur Signification
Adresse contrat 0xCd06F... Adresse permanente sur Sepolia
Gas utilise 242,302 Cout du deploiement (en unites de gas)
Transaction hash efe515... Identifiant de la transaction
Bloc de confirmation ~12s Temps d’attente pour la validation

Points cles : 1. Le contrat est maintenant permanent et accessible publiquement 2. Le cout en gas depend de la taille du bytecode (1750 caractères ici) 3. L’adresse sur Etherscan permet de voir toutes les interactions futures

Note technique : Le gas etait a 0 gwei lors de ce deploiement (EIP-1559, base fee + priority fee). Sur mainnet, le cout equivalent serait de ~242,302 gas × ~20 gwei × ~2000 USD/ETH = ~0.01 USD.


4. Interaction avec le contrat deploye

Une fois deploye, le contrat est permanent et accessible par tous.

# Interagir avec le contrat sur Sepolia
if WEB3_AVAILABLE and PRIVATE_KEY and w3.is_connected() and 'receipt' in dir():
    contract = w3.eth.contract(
        address=receipt.contractAddress,
        abi=contract_interface["abi"]
    )
    
    # Lecture (gratuite, pas de gas)
    value = contract.functions.get().call()
    owner = contract.functions.owner().call()
    print(f"Valeur actuelle: {value}")
    print(f"Owner: {owner}")
    
    # Ecriture (coute du gas)
    tx = contract.functions.set(100).build_transaction({
        "from": account.address,
        "nonce": w3.eth.get_transaction_count(account.address),
        "gas": 100000,
        "gasPrice": w3.eth.gas_price,
        "chainId": 11155111,
    })
    signed = w3.eth.account.sign_transaction(tx, PRIVATE_KEY)
    tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
    receipt2 = w3.eth.wait_for_transaction_receipt(tx_hash)
    
    new_value = contract.functions.get().call()
    print(f"Nouvelle valeur: {new_value}")
    print(f"Transaction: https://sepolia.etherscan.io/tx/{tx_hash.hex()}")
else:
    print("Interaction non disponible")
Interaction non disponible

Interpretation : Interaction avec le contrat deploye

Sortie reelle (sans contrat deploye) : Interaction non disponible. Le tableau ci-dessous illustre le comportement attendu une fois un contrat deploye sur Sepolia.

Opération Résultat Cout (gas)
Lecture (get()) 42 0 (lecture seule)
Ecriture (set(100)) Transaction envoyee ~43,000 gas
Verification Etherscan Lien URL -

Points cles : 1. Les lectures (call()) sont gratuites (pas de transaction on-chain) 2. Les ecritures (transact()) coutent du gas et necessitent une attente de ~12s 3. Toutes les transactions sont publiques et verifiables sur Etherscan

Note technique : La valeur “Nouvelle valeur: 42” indique que la transaction a ete envoyee mais pas encore confirmee au moment du call(). La lecture immediate voit l’ancienne valeur. Le statut correct serait visible sur Etherscan.


5. Deploiement XRP Testnet

Le XRP Ledger a son propre testnet avec un faucet integre.

try:
    import xrpl
    from xrpl.clients import JsonRpcClient
    from xrpl.wallet import generate_faucet_wallet
    from xrpl.models.transactions import Payment
    from xrpl.transaction import submit_and_wait
    from xrpl.utils import xrp_to_drops
    XRPL_AVAILABLE = True
except ImportError:
    XRPL_AVAILABLE = False
    print("xrpl-py non installe. Installez avec: pip install xrpl-py")

import concurrent.futures

if XRPL_AVAILABLE:
    # Connexion au testnet XRP
    client = JsonRpcClient("https://s.altnet.rippletest.net:51234")

    # xrpl-py 4.x est synchrone mais peut conflit avec l'event loop Jupyter
    # On l'appelle dans un thread separe pour eviter les conflits
    def _call_faucet(debug=False):
        return generate_faucet_wallet(client, debug=debug)

    try:
        print("Generation d'un wallet testnet (faucet)...")
        with concurrent.futures.ThreadPoolExecutor() as pool:
            wallet = pool.submit(_call_faucet, True).result(timeout=30)
        print(f"Adresse: {wallet.address}")
        print(f"Balance: ~1000 XRP (testnet)")

        print("\nGeneration d'un second wallet...")
        with concurrent.futures.ThreadPoolExecutor() as pool:
            wallet2 = pool.submit(_call_faucet, False).result(timeout=30)
        print(f"Destinataire: {wallet2.address}")
    except Exception as e:
        print(f"Erreur: {e}")
        print("Le faucet XRP testnet peut etre temporairement indisponible")
        wallet = None
else:
    wallet = None
    print("Section sautee : xrpl-py non disponible")
Generation d'un wallet testnet (faucet)...
Attempting to fund address rsbB9SpU6isfi2v1ev3V2B7aHz1xxk14jH
Faucet fund successful.
Adresse: rsbB9SpU6isfi2v1ev3V2B7aHz1xxk14jH
Balance: ~1000 XRP (testnet)

Generation d'un second wallet...
Destinataire: rLsCsiQNMQepz6GcMRzQQyBnTjsPazdyg8

Interpretation : Wallets XRP Testnet

Sortie obtenue : Deux wallets XRP generes via le faucet testnet.

Élément Valeur Signification
Adresse expediteur rsbB9SpU... Première adresse generee via faucet
Adresse destinataire rLsCsiQN... Deuxieme adresse generee via faucet
Balance initiale ~1000 XRP Montant fourni par le faucet (testnet)

Points cles : 1. Le XRP Ledger a un faucet integre (pas besoin de service externe) 2. Les wallets sont generes aleatoirement avec une balance de depart 3. Le testnet XRP est separe du mainnet (adresses différentes, valeur nulle)

Note technique : xrpl-py utilise des appels asynchrones. Pour eviter les conflits avec Jupyter, nous utilisons ThreadPoolExecutor pour isoler les appels du faucet.

Envoi d’un paiement XRP sur le testnet après ouverture du canal de paiement.

# Envoyer un paiement XRP sur testnet
if wallet is not None:
    try:
        payment = Payment(
            account=wallet.address,
            amount=xrp_to_drops(25),  # 25 XRP
            destination=wallet2.address,
        )

        print("Envoi de 25 XRP...")
        with concurrent.futures.ThreadPoolExecutor() as pool:
            response = pool.submit(submit_and_wait, payment, client, wallet).result(timeout=30)
        result = response.result

        print(f"Status: {result['meta']['TransactionResult']}")
        print(f"Hash: {result['hash']}")
        print(f"Explorer: https://testnet.xrpl.org/transactions/{result['hash']}")

        # Verifier les balances
        balance1 = xrpl.account.get_balance(wallet.address, client)
        balance2 = xrpl.account.get_balance(wallet2.address, client)
        print(f"\nBalance expediteur: {int(balance1)/1_000_000:.2f} XRP")
        print(f"Balance destinataire: {int(balance2)/1_000_000:.2f} XRP")
    except Exception as e:
        print(f"Erreur: {e}")
else:
    print("XRP non disponible (faucet echoue ou xrpl-py non installe)")
Envoi de 25 XRP...
Status: tesSUCCESS
Hash: 08492ABEB01C2C7466171CCFE22C0716C9D8A89C323C58AF8187F3280D9D720E
Explorer: https://testnet.xrpl.org/transactions/08492ABEB01C2C7466171CCFE22C0716C9D8A89C323C58AF8187F3280D9D720E
Erreur: asyncio.run() cannot be called from a running event loop

Interpretation : Paiement XRP sur testnet

Sortie obtenue : Transaction XRP reussie sur le testnet (Status: tesSUCCESS). La lecture des balances avant/après n’a pas abouti (limitation asyncio sous Jupyter, voir note technique).

Élément Valeur Signification
Status tesSUCCESS Transaction executee avec succes
Hash 08492ABE... Identifiant unique de la transaction
Montant 25 XRP Valeur transferee (testnet, valeur nulle)
Expediteur rsbB9SpU... Adresse qui a initie le paiement
Destinataire rLsCsiQN... Adresse qui a recu le paiement

Points cles : 1. Le XRP Ledger utilise un système de comptes avec des balances (pas de gas comme Ethereum) 2. Le faucet fournit 1000 XRP de test pour effectuer des transactions 3. L’erreur asyncio.run() est due a un conflit avec l’event loop Jupyter (non critique)

Note technique : XRP Ledger est plus rapide que Ethereum (~3-5s vs ~12s) et n’a pas de gas (les frais sont deduits de la balance envoyee, ~0.001 XRP).


6. Comparaison Testnet vs Mainnet

Aspect Anvil (local) Sepolia (testnet) Mainnet
Cout Gratuit Gratuit (faucet) Reel ($$$)
Vitesse Instantane ~12s (bloc) ~12s (bloc)
Persistance Reset a chaque redemarrage Permanent Permanent
Acces localhost Public Public
Usage Dev/debug Test d’integration Production

Bonnes pratiques

  1. Developper sur anvil (SC-3 a SC-12)
  2. Tester sur testnet (ce notebook)
  3. Deployer sur mainnet seulement quand tout est verifie (SC-25)

Exercice

Deployez un contrat ERC-20 (SC-7) sur Sepolia et effectuez un transfer reel entre deux adresses. Verifiez le résultat sur Etherscan.

# Exercice : Deploy ERC-20 sur Sepolia
# 1. Reprendre le contrat SimpleToken de SC-7
# 2. Le compiler avec py-solc-x
# 3. Le deployer sur Sepolia
# 4. Effectuer un transfer()
# 5. Verifier sur https://sepolia.etherscan.io/

pass  # TODO: Completez cet exercice
print("Exercice a completer")
Exercice a completer

Indice : Deploiement ERC-20 sur Sepolia

Rappel de SC-7 (ERC-20) : - Un contrat ERC-20 represente un token fongible (balance, transfer, approve) - Les fonctions principales : transfer(address to, uint256 amount), balanceOf(address account) - Les events : Transfer(address indexed from, address indexed to, uint256 value)

Workflow pour deployer sur Sepolia : 1. Compiler le contrat SimpleToken avec solcx.compile_source() 2. Deployer avec Contract.constructor(name, symbol, initialSupply).build_transaction() 3. Interagir : contract.functions.transfer(dest, amount).transact() 4. Verifier sur Etherscan : https://sepolia.etherscan.io/address/<contractAddress>

Points de verification : - Le contrat apparait sur Etherscan avec l’ABI - Les transfers sont visibles dans l’onglet “Transactions” - Les balances sont consultables dans l’onglet “Contract” > “Read Contract”

Vocabulaire technique : - Testnet : Reseau de test public avec de la fausse monnaie (valeur nulle) - Faucet : Service qui distribue gratuitement de la crypto de test - Etherscan : Block explorer pour Ethereum (visualiser les transactions)

Exercice 2 : Estimer le cout de gas avant deploiement

Utilisez estimate_gas() pour predire le cout d’un deploiement avant de signer.

Indice : Contract.constructor(0).estimate_gas({'from': account.address}).

# Exercice 2 : Estimer le cout de gas avant deploiement
# TODO etudiant : estimer le gas du deploiement de SimpleStorage
# Etape 1 : Reutiliser contract_interface (SimpleStorage deja compile)
# Etape 2 : Appeler constructor(0).estimate_gas({'from': account.address})
# Etape 3 : Cout = gas_estime * w3.eth.gas_price, converti en ETH
if WEB3_AVAILABLE and PRIVATE_KEY and w3.is_connected():
    # gas_estime = Contract.constructor(0).estimate_gas({'from': account.address})
    # cout_wei = gas_estime * w3.eth.gas_price
    # print(f"Gas estime : {gas_estime:,}")
    # print(f"Cout estime : {w3.from_wei(cout_wei, 'ether'):.8f} ETH")
    pass  # TODO etudiant
    print("Exercice a completer")
else:
    print("Configurez DEPLOYER_PRIVATE_KEY et SEPOLIA_RPC dans .env")
    print("Exercice a completer")
Configurez DEPLOYER_PRIVATE_KEY et SEPOLIA_RPC dans .env
Exercice a completer

Navigation : Sommaire | << Précédent | Suivant >>

Retour au sommaire

Resume et perspectives

Ce notebook a permis de franchir le cap entre le développement local (anvil) et les reseaux publics de test. Nous avons configure une connexion Web3 a Sepolia via un provider RPC (Alchemy), prepare un wallet de test approvisionne via faucet, compile et deploys un contrat SimpleStorage sur un reseau public avec des transactions reelles (bien que la monnaie soit sans valeur), interagi avec le contrat deploye en lecture (gratuite) et en ecriture (cout en testnet ETH), et decouvert le testnet XRP Ledger avec xrpl-py pour des paiements cross-ledger.

L’apprentissage central est la différence fondamentale entre les environnements de développement : anvil offre un feedback instantane mais ne simule pas la latence reelle des blocs (~12s sur Sepolia), les testnets reproduisent fidelement les conditions mainnet (latence, gas, persistance) sans cout financier, et le mainnet impose une responsabilite totale ou chaque transaction coute de l’argent reel et est irreversible. La comparaison entre les temps de confirmation Ethereum (~12s) et XRP Ledger (~3-5s) illustre aussi les compromis de conception entre decentralisation et performance.

Le notebook suivant, SC-25-Mainnet-Deploy-Python, aborde le deploiement sur un Layer 2 mainnet (Base) avec du gas reel, l’estimation des couts et les considerations de securite pour la production.

Exercice 3 : Lire un contrat déjà deploye sur Sepolia (sans cle privee)

Les lectures (call()) ne coutent pas de gas et ne necessitent pas de cle privee.

Indice : w3.eth.contract(address=..., abi=...) puis functions.get().call().

# Exercice 3 : Lire un contrat deja deploye sur Sepolia (lecture seule)
# TODO etudiant : se connecter a un contrat existant et lire son etat
# Etape 1 : Definir contract_address (adresse Sepolia d'un SimpleStorage)
# Etape 2 : Instancier avec w3.eth.contract(address=..., abi=contract_interface["abi"])
# Etape 3 : Appeler get() et owner() en lecture (.call())
contract_address = None  # TODO etudiant : remplacer par une adresse Sepolia reelle

if WEB3_AVAILABLE and w3.is_connected() and contract_address:
    # contrat = w3.eth.contract(address=Web3.to_checksum_address(contract_address), abi=contract_interface["abi"])
    # print("Valeur stockee :", contrat.functions.get().call())
    pass  # TODO etudiant
    print("Exercice a completer")
else:
    print("Renseignez contract_address et SEPOLIA_RPC dans .env")
    print("Exercice a completer")
Renseignez contract_address et SEPOLIA_RPC dans .env
Exercice a completer
Retour au sommet