Programmes
Sur Solana, les "contrats intelligents" sont appelés programmes. Les programmes sont déployés sur la chaîne dans des comptes qui contiennent le binaire exécutable compilé du programme. Les utilisateurs interagissent avec les programmes en envoyant des transactions contenant des instructions qui indiquent au programme ce qu'il doit faire.
Points clés
- Les programmes sont des comptes contenant du code exécutable, organisé en fonctions appelées instructions.
- Bien que les programmes soient sans état, ils peuvent inclure des instructions qui créent et mettent à jour d'autres comptes pour stocker des données.
- Une autorité de mise à jour peut modifier les programmes. Une fois cette autorité supprimée, le programme devient immuable.
- Les utilisateurs peuvent vérifier que les données d'un compte de programme sur la chaîne correspondent à son code source public grâce à des builds vérifiables.
Écrire des programmes Solana
Les programmes Solana sont principalement écrits dans le langage de programmation Rust, avec deux approches courantes pour le développement :
-
Anchor : Un framework conçu pour le développement de programmes Solana. Il offre une façon plus rapide et plus simple d'écrire des programmes, en utilisant des macros Rust pour réduire le code répétitif. Pour les débutants, il est recommandé de commencer avec le framework Anchor.
-
Rust natif : Cette approche consiste à écrire des programmes Solana en Rust sans utiliser de frameworks. Elle offre plus de flexibilité mais s'accompagne d'une complexité accrue.
Mettre à jour des programmes Solana
Pour en savoir plus sur le déploiement et la mise à jour des programmes, consultez la page déploiement des programmes.
Les programmes peuvent être
directement modifiés
par un compte désigné comme "autorité de mise à jour", qui est généralement le
compte ayant initialement déployé le programme. Si
l'autorité de mise à jour
est révoquée et définie sur None
, le programme devient immuable et ne peut
plus être mis à jour.
Programmes vérifiables
Les builds vérifiables permettent à quiconque de vérifier si le code on-chain d'un programme correspond à son code source public, rendant possible la détection de divergences entre les versions source et déployées.
La communauté des développeurs Solana a introduit des outils pour soutenir les builds vérifiables, permettant aux développeurs comme aux utilisateurs de vérifier que les programmes on-chain reflètent fidèlement leur code source partagé publiquement.
-
Recherche de programmes vérifiés : Pour vérifier rapidement les programmes vérifiés, les utilisateurs peuvent rechercher une adresse de programme sur Solana Explorer. Consultez un exemple de programme vérifié ici.
-
Outils de vérification : Le Solana Verifiable Build CLI d'Ellipsis Labs permet aux utilisateurs de vérifier indépendamment les programmes on-chain par rapport au code source publié.
-
Support pour les builds vérifiables dans Anchor : Anchor fournit un support intégré pour les builds vérifiables. Les détails sont disponibles dans la documentation d'Anchor.
Berkeley Packet Filter (BPF)
Solana utilise LLVM (Low Level Virtual Machine) pour compiler des programmes en fichiers ELF (Executable and Linkable Format). Ces fichiers contiennent la version personnalisée de Solana du bytecode eBPF, appelée "Solana Bytecode Format" (sBPF). Le fichier ELF contient le binaire du programme et est stocké on-chain dans un compte exécutable lorsque le programme est déployé.
Programmes intégrés
Programmes chargeurs
Chaque programme est lui-même détenu par un autre programme, qui est son chargeur. Actuellement, cinq programmes chargeurs existent :
Chargeur | ID du programme | Notes | Lien vers les instructions |
---|---|---|---|
native | NativeLoader1111111111111111111111111111111 | Possède les quatre autres chargeurs | — |
v1 | BPFLoader1111111111111111111111111111111111 | Les instructions de gestion sont désactivées, mais les programmes s'exécutent toujours | — |
v2 | BPFLoader2111111111111111111111111111111111 | Les instructions de gestion sont désactivées, mais les programmes s'exécutent toujours | Instructions |
v3 | BPFLoaderUpgradeab1e11111111111111111111111 | Est en cours d'élimination progressive | Instructions |
v4 | LoaderV411111111111111111111111111111111111 | v4 devrait devenir le chargeur standard | Instructions |
Ces chargeurs sont nécessaires pour créer et gérer des programmes personnalisés :
- Déployer un nouveau programme ou tampon
- Fermer un programme ou tampon
- Redéployer / mettre à niveau un programme existant
- Transférer l'autorité sur un programme
- Finaliser un programme
Loader-v3 et loader-v4 prennent en charge les modifications des programmes après leur déploiement initial. La permission de le faire est régulée par l'autorité d'un programme car la propriété du compte de chaque programme réside avec le chargeur.
Programmes précompilés
Programme Ed25519
Programme | ID du programme | Description | Instructions |
---|---|---|---|
Programme Ed25519 | Ed25519SigVerify111111111111111111111111111 | Vérifie les signatures ed25519. Si une signature échoue, une erreur est renvoyée. | Instructions |
Le programme ed25519 traite une instruction. Le premier u8
est un compteur du
nombre de signatures à vérifier, suivi d'un octet de remplissage. Ensuite, la
structure suivante est sérialisée, une pour chaque signature à vérifier.
struct Ed25519SignatureOffsets {signature_offset: u16, // offset to ed25519 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to public key of 32 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
Le pseudo-code de la vérification de signature :
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionsinstruction_index = ed25519_signature_instruction_index != u16::MAX ? ed25519_signature_instruction_index : current_instruction;signature = instructions[instruction_index].data[ed25519_signature_offset..ed25519_signature_offset + 64]instruction_index = ed25519_pubkey_instruction_index != u16::MAX ? ed25519_pubkey_instruction_index : current_instruction;pubkey = instructions[instruction_index].data[ed25519_pubkey_offset..ed25519_pubkey_offset + 32]instruction_index = ed25519_message_instruction_index != u16::MAX ? ed25519_message_instruction_index : current_instruction;message = instructions[instruction_index].data[ed25519_message_data_offset..ed25519_message_data_offset + ed25519_message_data_size]if pubkey.verify(signature, message) != Success {return Error}}return Success}
Programme Secp256k1
Programme | ID du programme | Description | Instructions |
---|---|---|---|
Programme Secp256k1 | KeccakSecp256k11111111111111111111111111111 | Vérifie les opérations de récupération de clé publique secp256k1 (ecrecover). | Instructions |
Le programme secp256k1 traite une instruction qui prend comme premier octet un compteur de la structure suivante sérialisée dans les données d'instruction :
struct Secp256k1SignatureOffsets {secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytessecp_signature_instruction_index: u8, // instruction index to find signaturesecp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytessecp_pubkey_instruction_index: u8, // instruction index to find pubkeysecp_message_data_offset: u16, // offset to start of message datasecp_message_data_size: u16, // size of message datasecp_message_instruction_index: u8, // instruction index to find message data}
Le pseudo-code de la vérification de récupération :
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionssignature = instructions[secp_signature_instruction_index].data[secp_signature_offset..secp_signature_offset + 64]recovery_id = instructions[secp_signature_instruction_index].data[secp_signature_offset + 64]ref_eth_pubkey = instructions[secp_pubkey_instruction_index].data[secp_pubkey_offset..secp_pubkey_offset + 20]message_hash = keccak256(instructions[secp_message_instruction_index].data[secp_message_data_offset..secp_message_data_offset + secp_message_data_size])pubkey = ecrecover(signature, recovery_id, message_hash)eth_pubkey = keccak256(pubkey[1..])[12..]if eth_pubkey != ref_eth_pubkey {return Error}}return Success}
Cela permet à l'utilisateur de spécifier n'importe quelles données d'instruction dans la transaction pour les données de signature et de message. En spécifiant une sysvar d'instructions spéciale, on peut aussi recevoir des données de la transaction elle-même.
Le coût de la transaction comptera le nombre de signatures à vérifier multiplié par le multiplicateur de coût de vérification de signature.
Programme Secp256r1
Programme | ID du programme | Description | Instructions |
---|---|---|---|
Programme Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Vérifie jusqu'à 8 signatures secp256r1. Prend une signature, une clé publique et un message. Renvoie une erreur en cas d'échec. | Instructions |
Le programme secp256r1 traite une instruction. Le premier u8
est un compteur
du nombre de signatures à vérifier, suivi d'un octet de remplissage. Ensuite, la
structure suivante est sérialisée, une pour chaque signature à vérifier :
struct Secp256r1SignatureOffsets {signature_offset: u16, // offset to compact secp256r1 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to compressed public key of 33 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
Le pseudo-code de la vérification de signature :
process_instruction() {if data.len() < SIGNATURE_OFFSETS_START {return Error}num_signatures = data[0] as usizeif num_signatures == 0 || num_signatures > 8 {return Error}expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_STARTif data.len() < expected_data_size {return Error}for i in 0..num_signatures {offsets = parse_signature_offsets(data, i)signature = get_data_slice(data, instruction_datas, offsets.signature_instruction_index, offsets.signature_offset, SIGNATURE_SERIALIZED_SIZE)if s > half_curve_order {return Error}pubkey = get_data_slice(data, instruction_datas, offsets.public_key_instruction_index, offsets.public_key_offset, COMPRESSED_PUBKEY_SERIALIZED_SIZE)message = get_data_slice(data, instruction_datas, offsets.message_instruction_index, offsets.message_data_offset, offsets.message_data_size)if !verify_signature(signature, pubkey, message) {return Error}}return Success}
Remarque : les valeurs S basses sont imposées pour toutes les signatures afin d'éviter une malléabilité accidentelle des signatures.
Programmes de base
La genèse du cluster Solana inclut une liste de programmes spéciaux qui fournissent des fonctionnalités de base pour le réseau. Historiquement, ils étaient appelés programmes "natifs" et étaient distribués avec le code du validator.
Programme | ID du programme | Description | Instructions |
---|---|---|---|
System Program | 11111111111111111111111111111111 | Crée de nouveaux comptes, alloue des données de compte, assigne des comptes aux programmes propriétaires, transfère des lamports depuis les comptes appartenant au System Program et paie les frais de transaction. | SystemInstruction |
Programme de vote | Vote111111111111111111111111111111111111111 | Crée et gère des comptes qui suivent l'état de vote des validators et les récompenses. | VoteInstruction |
Programme de stake | Stake11111111111111111111111111111111111111 | Crée et gère des comptes représentant les stakes et les récompenses pour les délégations aux validators. | StakeInstruction |
Programme de configuration | Config1111111111111111111111111111111111111 | Ajoute des données de configuration à la chaîne, suivies de la liste des clés publiques autorisées à les modifier. Contrairement aux autres programmes, le programme de configuration ne définit pas d'instructions individuelles. Il n'a qu'une seule instruction implicite : "store". Ses données d'instruction sont un ensemble de clés qui contrôlent l'accès au compte et les données à y stocker. | ConfigInstruction |
Programme de budget de calcul | ComputeBudget111111111111111111111111111111 | Définit les limites et les prix des unités de calcul pour les transactions, permettant aux utilisateurs de contrôler les ressources de calcul et les frais de priorisation. | ComputeBudgetInstruction |
Programme de table de recherche d'adresses | AddressLookupTab1e1111111111111111111111111 | Gère les tables de recherche d'adresses, qui permettent aux transactions de référencer plus de comptes que ce qui pourrait normalement tenir dans la liste de comptes de la transaction. | ProgramInstruction |
Programme de preuve ZK ElGamal | ZkE1Gama1Proof11111111111111111111111111111 | Fournit une vérification de preuve à connaissance nulle pour les données chiffrées avec ElGamal. | — |
Is this page helpful?