Deploiement et operations#

Un programme Solana parfaitement ecrit et rigoureusement teste ne vaut rien tant qu’il n’est pas deploye sur un cluster accessible aux utilisateurs. Le deploiement est le moment ou le code quitte l’environnement controle du developpeur pour entrer dans un univers hostile : transactions concurrentes, acteurs malveillants, et consequences financieres irreversibles. Solana structure cette transition par un systeme de clusters progressifs — devnet, testnet, mainnet-beta — qui permettent de valider le comportement du programme a chaque etape avant de l’exposer aux fonds reels.

Mais le deploiement n’est que le debut. Un programme en production doit etre surveille, mis a jour avec precaution, et gouverne de maniere transparente. Le modele de programmes evolutifs (upgradeable programs) de Solana offre une flexibilite remarquable : le bytecode peut etre remplace sans changer l’adresse du programme, ce qui preserve les integrations existantes. Cette flexibilite s’accompagne cependant de responsabilites considerables — une mise a jour mal preparee peut affecter tous les utilisateurs instantanement.

Ce chapitre couvre l’ensemble du cycle de vie operationnel d’un programme Solana. Nous commencerons par le deploiement progressif a travers les clusters, puis nous detaillerons le mecanisme de mise a jour des programmes, les outils de monitoring, la generation de clients a partir de l’IDL, et enfin les pratiques de gouvernance et de securite operationnelle indispensables en production.

Cycle de deploiement#

Solana propose trois clusters publics, chacun jouant un role distinct dans le cycle de vie d’un programme. Le passage de l’un a l’autre constitue un pipeline de deploiement progressif, analogue aux environnements staging et production du developpement web classique.

Définition 153 (Cycle de deploiement : devnet, testnet, mainnet-beta)

Le cycle de deploiement d’un programme Solana suit une progression en trois etapes a travers les clusters publics :

  1. Devnet — environnement de developpement et de test. Le SOL y est gratuit, obtenu via airdrop (solana airdrop 2). Le cluster est reinitialise periodiquement. C’est l’environnement principal pour le developpement quotidien et les tests d’integration.

  2. Testnet — environnement de test de performance. Il fonctionne de maniere similaire au mainnet (memes validateurs, memes mecanismes de consensus) mais utilise des tokens de test sans valeur. Il sert a valider le comportement du programme sous des conditions realistes de charge et de latence.

  3. Mainnet-beta — environnement de production. Le SOL y a une valeur reelle et les deploiements coutent des frais. Toute erreur a ce stade a des consequences financieres. Le suffixe beta est historique et ne reflete plus le niveau de maturite du reseau.

Chaque cluster possede ses propres validateurs, son propre etat, et ses propres adresses RPC. Un programme deploye sur devnet n’existe pas sur mainnet — il faut le deployer separement sur chaque cluster.

Le deploiement avec Anchor s’effectue via la commande anchor deploy, qui compile le programme, le deploie sur le cluster configure, et met a jour les fichiers de reference locaux.

# Deployer sur devnet
anchor deploy --provider.cluster devnet

# Deployer sur testnet
anchor deploy --provider.cluster testnet

# Deployer sur mainnet-beta
anchor deploy --provider.cluster mainnet-beta

# Ou utiliser la configuration par defaut definie dans Anchor.toml
anchor deploy

Exemple 50 (Deploiement initial sur devnet)

Le deploiement initial d’un programme sur devnet suit une sequence typique :

# 1. Configurer le CLI pour devnet
solana config set --url devnet

# 2. Obtenir du SOL de test (necessaire pour payer le deploiement)
solana airdrop 5

# 3. Generer la paire de cles du programme
solana-keygen new -o target/deploy/my_program-keypair.json

# 4. Compiler et deployer
anchor build
anchor deploy --provider.cluster devnet

# 5. Verifier le deploiement
solana program show $(solana-keygen pubkey target/deploy/my_program-keypair.json)

Le cout du deploiement depend de la taille du binaire compile. Un programme Anchor typique occupe entre 200 Ko et 1 Mo, et le deploiement coute entre 1 et 5 SOL en loyer pour le compte de donnees du programme. Ce loyer est recuperable si le programme est ferme.

La configuration des clusters et des programmes est centralisee dans le fichier Anchor.toml a la racine du projet.

[toolchain]
anchor_version = "0.30.1"

[features]
resolution = true

[programs.devnet]
my_program = "DevPrG1m1111111111111111111111111111111111"

[programs.testnet]
my_program = "TstPrG1m2222222222222222222222222222222222"

[programs.mainnet]
my_program = "PrdPrG1m3333333333333333333333333333333333"

[registry]
url = "https://api.apr.dev"

[provider]
cluster = "devnet"
wallet = "~/.config/solana/devnet-deployer.json"

[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

Remarque 119 (Identifiants de programme distincts par cluster)

Chaque cluster doit utiliser un identifiant de programme (Program ID) distinct. Cette separation est une mesure de securite fondamentale. Si un meme Program ID etait utilise sur devnet et mainnet, une erreur de configuration pourrait conduire a deployer du code de test sur le cluster de production, ou inversement a pointer des clients de production vers un programme de developpement.

La bonne pratique consiste a generer une paire de cles dediee pour chaque cluster :

# Generer des cles de deploiement par cluster
solana-keygen new -o deploy-keys/devnet-program.json
solana-keygen new -o deploy-keys/testnet-program.json
solana-keygen new -o deploy-keys/mainnet-program.json

Le declare_id!() dans le code Rust doit correspondre au Program ID du cluster cible. Anchor gere cette correspondance automatiquement via les sections [programs.*] du fichier Anchor.toml.

Upgrade de programmes#

Contrairement aux contrats Ethereum qui sont immutables par defaut, les programmes Solana sont evolutifs (upgradeable) par construction. Le mecanisme repose sur le BPF Loader, qui separe l’adresse du programme de son bytecode executable.

Définition 154 (Programme evolutif (Upgradeable Program))

Un programme evolutif est un programme Solana dont le bytecode peut etre remplace sans changer son adresse on-chain. Le BPF Loader Upgradeable (BPFLoaderUpgradeab1e11111111111111111111111) maintient deux comptes distincts :

  1. Le Program Account — contient un pointeur vers le compte de donnees executable. Son adresse est le Program ID stable utilise par les clients.

  2. Le Program Data Account — contient le bytecode ELF compile du programme. C’est ce compte qui est remplace lors d’une mise a jour.

Lors d’un upgrade, le processus est le suivant :

  1. Le nouveau bytecode est telecharge dans un Buffer Account temporaire.

  2. La commande d’upgrade remplace atomiquement le pointeur du Program Data Account vers le nouveau bytecode.

  3. L’ancien Buffer est libere et son loyer recupere.

Ce mecanisme garantit que le Program ID reste identique, preservant toutes les integrations, PDAs et references existantes.

Les commandes suivantes illustrent le processus de mise a jour.

# Compiler le programme modifie
anchor build

# Deployer la mise a jour sur devnet
anchor upgrade --program-id DevPrG1m1111111111111111111111111111111111 \
  target/deploy/my_program.so \
  --provider.cluster devnet

# Verifier le programme deploye
solana program show DevPrG1m1111111111111111111111111111111111

Définition 155 (Autorite de mise a jour (Upgrade Authority))

L”autorite de mise a jour (upgrade authority) est la paire de cles autorisee a modifier le bytecode d’un programme deploye. Par defaut, c’est la cle utilisee lors du deploiement initial.

L’autorite peut etre :

  • Transferee a une autre cle publique (par exemple, un multisig ou une DAO).

  • Revoquee definitivement en la mettant a None, ce qui rend le programme immutable — plus aucune mise a jour ne sera jamais possible.

L’immutabilite est un signal de confiance maximal envers les utilisateurs : le code ne changera plus. Mais c’est aussi irreversible : un bug non corrigeable dans un programme immutable peut avoir des consequences desastreuses.

La commande suivante rend un programme definitivement immutable.

# Rendre le programme immutable (IRREVERSIBLE)
solana program set-upgrade-authority <PROGRAM_ID> --final

# Transferer l'autorite a un autre detenteur (par exemple un multisig)
solana program set-upgrade-authority <PROGRAM_ID> \
  --new-upgrade-authority <NOUVELLE_CLE_PUBLIQUE>

Remarque 120 (Risques lies aux mises a jour)

Une mise a jour de programme modifie le comportement pour tous les utilisateurs instantanement. Il n’existe pas de deploiement progressif (canary) ni de rollback automatique. Les risques principaux sont :

  • Incompatibilite des donnees : si la nouvelle version modifie le schema des comptes (ajout, suppression ou reordonnancement de champs), les comptes existants deviennent illisibles.

  • Changement de comportement non anticipe : une instruction qui fonctionnait d’une certaine maniere peut soudainement se comporter differemment, cassant les integrations des clients.

  • Fenetre de vulnerabilite : entre le deploiement et la detection d’un bug, tous les utilisateurs sont exposes.

Les bonnes pratiques incluent : tester exhaustivement sur devnet et testnet avant toute mise a jour mainnet, utiliser un mecanisme de timelock (delai obligatoire entre l’annonce et l’execution de la mise a jour), et soumettre la mise a jour a un vote de gouvernance lorsque le programme gere des fonds significatifs.

Remarque 121 (Verification du code source avec anchor verify)

La commande anchor verify prouve que le bytecode deploye sur un cluster correspond exactement au code source publie. Elle recompile le programme a partir du code source dans un environnement reproductible (Docker) et compare le hash du binaire obtenu avec celui du programme on-chain.

# Verifier que le bytecode deploye correspond au code source
anchor verify <PROGRAM_ID> --provider.cluster mainnet

Cette verification est essentielle pour la confiance : sans elle, les utilisateurs n’ont aucune garantie que le programme deploye fait bien ce que le code source publie decrit. Les protocoles serieux publient leur code source et encouragent la verification independante.

Monitoring et explorateurs#

Un programme deploye en production necessite une surveillance continue. Les explorateurs de blocs et les outils d’indexation permettent de suivre l’activite, detecter les anomalies et diagnostiquer les problemes.

Exemple 51 (Explorateurs de blocs Solana)

Les principaux explorateurs de blocs de l’ecosysteme Solana offrent des fonctionnalites complementaires :

  • Solana Explorer (explorer.solana.com) — l’explorateur officiel. Permet de visualiser les transactions, les comptes, les programmes et les blocs. Supporte tous les clusters (devnet, testnet, mainnet-beta).

  • Solscan (solscan.io) — explorateur communautaire avec une interface riche. Offre des fonctionnalites avancees comme l’analyse des tokens, le suivi des portefeuilles et les statistiques DeFi.

  • SolanaFM (solana.fm) — explorateur oriente developpeur. Propose un decodage automatique des instructions Anchor a partir de l’IDL on-chain, ce qui rend les transactions lisibles par les humains.

Pour inspecter un programme deploye, la commande CLI fournit les informations essentielles :

# Afficher les informations du programme deploye
solana program show <PROGRAM_ID>

# Sortie typique :
# Program Id: DevPrG1m1111111111111111111111111111111111
# Owner: BPFLoaderUpgradeab1e11111111111111111111111
# ProgramData Address: 5Kx9...3mN7
# Authority: FgPr...2kAb
# Last Deployed In Slot: 123456789
# Data Length: 245760 (0x3c000) bytes
# Balance: 1.7112 SOL

Exemple 52 (Webhooks Helius pour le suivi en temps reel)

Les services de webhooks permettent de recevoir des notifications en temps reel lorsque le programme est invoque. Helius est le principal fournisseur de webhooks sur Solana. La configuration se fait via leur API :

# Creer un webhook via l'API Helius (exemple conceptuel)
curl -X POST https://api.helius.xyz/v0/webhooks?api-key=<API_KEY> \
  -H "Content-Type: application/json" \
  -d '{
    "webhookURL": "https://mon-serveur.com/webhook",
    "transactionTypes": ["Any"],
    "accountAddresses": ["<PROGRAM_ID>"],
    "webhookType": "enhanced"
  }'

Le webhook enhanced decode automatiquement les instructions Anchor et envoie un payload JSON structure contenant le nom de l’instruction, les comptes impliques et les parametres deserialises. Cela permet de construire des alertes granulaires : notification en cas d’erreur, alerte si un transfert depasse un certain seuil, ou suivi des appels a une instruction specifique.

Remarque 122 (Logging en production et bonnes pratiques)

La journalisation en production sur Solana obeit a des contraintes specifiques liees au budget de compute units. Trois mecanismes sont disponibles, chacun avec ses compromis :

  1. msg!() — journalisation directe dans les logs de transaction. Chaque appel consomme des CU (entre 100 et plusieurs milliers selon la complexite). A utiliser avec parcimonie en production : reserver aux informations critiques (erreurs, etats inattendus).

  2. Evenements Anchor (#[event] / emit!()) — journalisation structuree. Les evenements sont serialises dans les logs de la transaction et parsables par les clients et les indexeurs. Ils consomment egalement des CU, mais offrent un format structuree adapte a l’analyse automatisee.

  3. Indexation off-chain — la strategie la plus efficace pour l’analytique. Des services comme Helius, Shyft ou The Graph indexent les transactions et les evenements de votre programme. Ils stockent les donnees dans des bases de donnees traditionnelles interrogeables via des API REST ou GraphQL, sans cout on-chain supplementaire.

La bonne pratique consiste a combiner les trois : msg!() minimal pour le debogage d’urgence, evenements pour les actions metier importantes, et indexation off-chain pour l’analytique complete (metriques d’utilisation, frais collectes, taux d’erreurs).

IDL et generation de clients#

L’IDL (Interface Definition Language) est le pont entre le programme Rust on-chain et les clients qui l’invoquent. Il decrit exhaustivement l’interface publique du programme dans un format JSON standardise.

Définition 156 (IDL (Interface Definition Language))

L”IDL (Interface Definition Language) est un fichier JSON genere par Anchor lors de la compilation (anchor build). Il decrit l’integralite de l’interface publique du programme :

  • Instructions : nom, parametres (avec types), comptes requis (avec contraintes de mutabilite et signataire).

  • Comptes : structures de donnees avec leurs champs et types.

  • Types : enumerations, structures imbriquees et alias de types.

  • Erreurs : codes d’erreur personnalises avec messages.

  • Evenements : structures emises par emit!().

Le fichier est genere dans target/idl/<nom_du_programme>.json et sert de contrat d’interface entre le programme et ses clients. A partir de ce fichier, les SDK Anchor generent automatiquement des clients types dans plusieurs langages.

La commande anchor build produit l’IDL aux cotes du binaire compile.

# Compiler le programme et generer l'IDL
anchor build

# L'IDL est genere dans :
# target/idl/my_program.json
# Le binaire compile dans :
# target/deploy/my_program.so

Définition 157 (Generation de clients types)

La generation de clients types est le processus par lequel un SDK transforme l’IDL JSON en une bibliotheque client dans un langage specifique. Le SDK @coral-xyz/anchor pour TypeScript est le plus mature : il produit un objet Program<T> generique ou T capture la structure complete de l’IDL.

Chaque instruction du programme devient une methode chainable avec :

  • Verification de types sur les parametres d’instruction.

  • Autocompletion sur les noms de comptes requis.

  • Deserialisation automatique des comptes lus on-chain.

  • Decodage des evenements emis par le programme.

Des clients similaires existent pour Python (anchorpy), Rust (anchor-client), et d’autres langages. La generation est possible pour tout langage capable de parser le JSON de l’IDL et de construire des transactions Solana.

Un client TypeScript utilise l’IDL pour construire des transactions de maniere typee et ergonomique.

import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { MyProgram } from "../target/types/my_program";
import { Connection, Keypair, PublicKey } from "@solana/web3.js";

// 1. Etablir la connexion au cluster
const connection = new Connection("https://api.devnet.solana.com");
const wallet = anchor.Wallet.local();
const provider = new anchor.AnchorProvider(connection, wallet, {
  commitment: "confirmed",
});
anchor.setProvider(provider);

// 2. Charger le programme a partir de l'IDL genere
const program = anchor.workspace.MyProgram as Program<MyProgram>;

// 3. Appeler une instruction avec autocompletion et verification de types
const tx = await program.methods
  .initialize()
  .accounts({
    counter: counterKeypair.publicKey,
    authority: wallet.publicKey,
    systemProgram: anchor.web3.SystemProgram.programId,
  })
  .signers([counterKeypair])
  .rpc();

console.log("Transaction signature:", tx);

// 4. Lire les donnees d'un compte (deserialisation automatique)
const account = await program.account.counter.fetch(counterKeypair.publicKey);
console.log("Count:", account.count.toNumber());

// 5. Ecouter les evenements du programme
const listener = program.addEventListener(
  "counterIncremented",
  (event, slot) => {
    console.log(`Compteur incremente a ${event.newCount} au slot ${slot}`);
  }
);

Remarque 123 (Publication de l’IDL on-chain)

L’IDL peut etre stocke directement on-chain via les commandes anchor idl init et anchor idl upgrade. Cette publication permet a n’importe quel developpeur de generer un client type pour votre programme sans avoir acces au code source.

# Publier l'IDL pour la premiere fois
anchor idl init <PROGRAM_ID> --filepath target/idl/my_program.json

# Mettre a jour l'IDL apres une modification du programme
anchor idl upgrade <PROGRAM_ID> --filepath target/idl/my_program.json

L’IDL on-chain est utilise par les explorateurs (notamment SolanaFM) pour decoder automatiquement les transactions en instructions lisibles. C’est un element cle de la transparence : les utilisateurs peuvent verifier exactement quelles instructions sont executees et avec quels parametres.

La visualisation suivante illustre le flux de generation de clients a partir du programme Rust source.

Hide code cell source

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import seaborn as sns

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.1)

fig, ax = plt.subplots(figsize=(14, 6))

palette = sns.color_palette("muted")

# Noeud source : Programme Rust
boxes = [
    ("Programme Rust\n(lib.rs)", -5, 3, 2.6, 0.8, palette[0]),
    ("anchor build", -0.5, 3, 2.2, 0.8, palette[4]),
    ("IDL\n(JSON)", -0.5, 1, 2.2, 0.8, palette[3]),
    ("Binaire\n(.so)", -4, 1, 2.2, 0.8, palette[1]),
    ("Client\nTypeScript", -4, -1, 2.2, 0.8, palette[2]),
    ("Client\nPython", -0.5, -1, 2.2, 0.8, palette[2]),
    ("Autres\nlangages", 3, -1, 2.2, 0.8, palette[2]),
]

for label, x, y, w, h, color in boxes:
    box = mpatches.FancyBboxPatch(
        (x - w / 2, y - h / 2), w, h,
        boxstyle="round,pad=0.1",
        facecolor=color, edgecolor="white", linewidth=2, alpha=0.9,
    )
    ax.add_patch(box)
    ax.text(x, y, label, ha="center", va="center",
            fontsize=9, fontweight="bold", color="white")

# Fleches
arrows = [
    ((-5, 3), (-0.5, 3)),       # Rust -> anchor build
    ((-0.5, 3), (-0.5, 1)),     # anchor build -> IDL
    ((-0.5, 3), (-4, 1)),       # anchor build -> Binaire
    ((-0.5, 1), (-4, -1)),      # IDL -> TypeScript
    ((-0.5, 1), (-0.5, -1)),    # IDL -> Python
    ((-0.5, 1), (3, -1)),       # IDL -> Autres
]

for (x1, y1), (x2, y2) in arrows:
    dx = x2 - x1
    dy = y2 - y1
    norm = (dx**2 + dy**2) ** 0.5
    # Raccourcir les fleches pour ne pas chevaucher les boites
    shrink_start = 0.55
    shrink_end = 0.55
    ax.annotate(
        "",
        xy=(x1 + dx * (1 - shrink_end / norm), y1 + dy * (1 - shrink_end / norm)),
        xytext=(x1 + dx * (shrink_start / norm), y1 + dy * (shrink_start / norm)),
        arrowprops=dict(arrowstyle="-|>", color="#555555", lw=1.8, mutation_scale=16),
    )

ax.set_xlim(-7.5, 5.5)
ax.set_ylim(-2.5, 4.5)
ax.set_aspect("equal")
ax.set_title(
    "Generation de clients a partir du programme Rust via l'IDL",
    fontsize=13, fontweight="bold",
)
ax.axis("off")

plt.show()
_images/2bb52f84605cec166e8ffd6e951dea467c8e31d90ccaa2c795ef26eebefc41c5.png

Operations et gouvernance#

La securite operationnelle d’un programme en production va bien au-dela du code. Elle englobe la gestion des cles, les mecanismes de mise a jour collective, et les procedures de reponse aux incidents.

Définition 158 (Multisig (Multi-signature))

Un multisig (multi-signature) est un mecanisme qui exige l’approbation de plusieurs signataires pour executer une action. Au lieu de confier l’autorite de mise a jour a une seule cle privee, un multisig distribue le controle entre \(n\) detenteurs et exige au minimum \(m\) signatures pour autoriser une operation (schema dit \(m\)-sur-\(n\)).

Sur Solana, Squads est le protocole de reference pour les multisigs. Il cree un PDA multisig qui detient l’autorite de mise a jour du programme. Une proposition de mise a jour doit etre :

  1. Soumise par un membre du multisig.

  2. Approuvee par au moins \(m\) membres (le threshold).

  3. Executee apres avoir atteint le quorum.

Ce mecanisme elimine le risque de point de defaillance unique (single point of failure) : la compromission d’une seule cle ne suffit plus pour modifier le programme.

# Concept : creation d'un multisig Squads (via le SDK Squads)
# 1. Creer un multisig avec 3 membres et un seuil de 2
squads-cli create-multisig \
  --member <CLE_MEMBRE_1> \
  --member <CLE_MEMBRE_2> \
  --member <CLE_MEMBRE_3> \
  --threshold 2

# 2. Transferer l'autorite de mise a jour du programme au PDA multisig
solana program set-upgrade-authority <PROGRAM_ID> \
  --new-upgrade-authority <MULTISIG_PDA>

# 3. Pour une mise a jour, un membre propose la transaction
squads-cli create-transaction \
  --multisig <MULTISIG_PDA> \
  --program-upgrade <PROGRAM_ID> \
  --buffer <BUFFER_ACCOUNT>

# 4. Les autres membres approuvent
squads-cli approve-transaction --transaction <TX_ID>

# 5. Une fois le seuil atteint, la transaction est executee
squads-cli execute-transaction --transaction <TX_ID>

La visualisation ci-dessous illustre l’architecture d’un multisig avec trois signataires et un seuil de deux approbations.

Hide code cell source

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import networkx as nx
import seaborn as sns

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.1)

G = nx.DiGraph()

# Noeuds
signers = ["Signataire A", "Signataire B", "Signataire C"]
for s in signers:
    G.add_node(s, type="signer")

G.add_node("Multisig PDA\n(seuil = 2/3)", type="multisig")
G.add_node("Upgrade\nAuthority", type="authority")
G.add_node("Programme\ndeploye", type="program")

# Aretes : signataires -> multisig -> upgrade authority -> programme
for s in signers:
    G.add_edge(s, "Multisig PDA\n(seuil = 2/3)")
G.add_edge("Multisig PDA\n(seuil = 2/3)", "Upgrade\nAuthority")
G.add_edge("Upgrade\nAuthority", "Programme\ndeploye")

# Disposition manuelle
pos = {
    "Signataire A": (-3, 2),
    "Signataire B": (0, 2),
    "Signataire C": (3, 2),
    "Multisig PDA\n(seuil = 2/3)": (0, 0),
    "Upgrade\nAuthority": (0, -2),
    "Programme\ndeploye": (0, -4),
}

palette = sns.color_palette("muted")

node_colors = []
node_sizes = []
for node in G.nodes():
    ntype = G.nodes[node].get("type")
    if ntype == "signer":
        node_colors.append(palette[0])
        node_sizes.append(1800)
    elif ntype == "multisig":
        node_colors.append(palette[3])
        node_sizes.append(2500)
    elif ntype == "authority":
        node_colors.append(palette[4])
        node_sizes.append(1800)
    else:
        node_colors.append(palette[1])
        node_sizes.append(2000)

fig, ax = plt.subplots(figsize=(10, 9))

nx.draw_networkx_edges(
    G, pos, ax=ax, edge_color="#888888", width=2.0,
    arrows=True, arrowsize=20, arrowstyle="-|>",
    connectionstyle="arc3,rad=0.0",
    min_source_margin=25, min_target_margin=25,
)
nx.draw_networkx_nodes(
    G, pos, ax=ax, node_color=node_colors,
    node_size=node_sizes, edgecolors="white", linewidths=2,
)
nx.draw_networkx_labels(
    G, pos, ax=ax, font_size=9, font_weight="bold",
)

legend_items = [
    mpatches.Patch(color=palette[0], label="Signataire (hardware wallet)"),
    mpatches.Patch(color=palette[3], label="Multisig PDA (Squads)"),
    mpatches.Patch(color=palette[4], label="Upgrade Authority"),
    mpatches.Patch(color=palette[1], label="Programme on-chain"),
]
ax.legend(handles=legend_items, loc="upper right", fontsize=9, framealpha=0.9)
ax.set_title(
    "Architecture multisig pour la gouvernance d'un programme Solana",
    fontsize=13, fontweight="bold",
)
ax.axis("off")

plt.show()
_images/97ef407d8cfed2389c74fa2ef49cb25a2bae3b795a85ae815f83889b4ad98c90.png

Exemple 53 (Gouvernance via Realms (SPL Governance))

Pour les protocoles DAO (Decentralized Autonomous Organization), Realms (base sur SPL Governance) offre un cadre de gouvernance plus riche qu’un simple multisig. Les detenteurs de tokens de gouvernance votent sur les propositions de mise a jour, et l’execution est automatisee une fois le quorum atteint.

Le flux typique est le suivant :

  1. Un membre de la DAO soumet une proposition de mise a jour du programme, incluant le buffer contenant le nouveau bytecode.

  2. Les detenteurs de tokens de gouvernance votent pendant une periode definie (par exemple, 3 jours).

  3. Si le quorum est atteint et la majorite est favorable, la proposition passe en etat executable.

  4. Apres un delai optionnel (cooldown), n’importe quel membre peut declencher l’execution, qui invoque solana program upgrade avec l’autorite de la DAO.

Ce mecanisme assure transparence et legitimite democratique pour les mises a jour de programmes gerant des fonds collectifs.

Remarque 124 (Checklist de securite operationnelle)

La securite operationnelle d’un programme en production repose sur plusieurs piliers complementaires :

Gestion des cles

  • Utiliser un hardware wallet (Ledger) pour l’autorite de mise a jour — jamais une cle stockee en clair sur disque.

  • Separer les cles de deploiement des cles d’autorite : la cle qui deploie initialement n’est pas necessairement celle qui controle les mises a jour.

  • Pratiquer la rotation des cles : transferer periodiquement l’autorite vers de nouvelles cles.

Controle des mises a jour

  • Configurer un multisig (Squads) pour l’autorite de mise a jour avec un seuil d’au moins 2 sur 3.

  • Imposer un delai (timelock) entre l’annonce d’une mise a jour et son execution, laissant le temps aux utilisateurs de reagir.

  • Publier le code source et encourager anchor verify pour la verification independante.

Surveillance et incidents

  • Configurer des webhooks (Helius) pour etre alerte lorsque le programme est invoque, en particulier pour les instructions sensibles (changement d’autorite, transferts importants).

  • Maintenir un tableau de bord de metriques : nombre de transactions, taux d’erreurs, compute units consommees.

  • Documenter un plan de reponse aux incidents : qui contacter, comment suspendre les operations (via une autorite de gel si applicable), comment deployer un correctif d’urgence.

Resume#

Concept

Description

Devnet

Cluster de developpement avec SOL gratuit par airdrop, reinitialise periodiquement

Testnet

Cluster de test de performance simulant les conditions du mainnet

Mainnet-beta

Cluster de production avec SOL reel et consequences financieres

Programme evolutif

Programme dont le bytecode peut etre remplace sans changer l’adresse on-chain

Upgrade Authority

Paire de cles autorisee a modifier le bytecode d’un programme deploye

Immutabilite

Revocation definitive de l’autorite de mise a jour via --final

anchor verify

Commande prouvant que le bytecode deploye correspond au code source publie

IDL

Fichier JSON decrivant l’interface publique du programme : instructions, comptes, types, erreurs

IDL on-chain

Publication de l’IDL directement sur la blockchain via anchor idl init

Multisig

Mecanisme exigeant \(m\) signatures parmi \(n\) pour executer une action (Squads)

Realms

Framework de gouvernance DAO permettant des votes sur les mises a jour de programmes

Webhooks

Notifications en temps reel lors de l’invocation du programme (Helius)

Explorateurs

Solana Explorer, Solscan, SolanaFM pour l’inspection des transactions et comptes

Securite operationnelle

Hardware wallet, multisig, timelock, monitoring, plan d’incident