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 quoi 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 à niveau peut mettre à jour 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.
Écriture de 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 méthode plus rapide et plus simple pour é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 implique l'écriture de programmes Solana en Rust sans utiliser de frameworks. Elle offre plus de flexibilité mais s'accompagne d'une complexité accrue.
Mise à jour des programmes Solana
Pour en savoir plus sur le déploiement et la mise à niveau 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 à niveau", qui est généralement le compte ayant initialement déployé le programme. Si l'autorité de mise à niveau est révoquée et définie sur null, 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 des divergences entre la version source et la version déployée.
La communauté des développeurs Solana a introduit des outils pour prendre en charge les builds vérifiables, permettant aux développeurs et 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 Anchor.
Berkeley Packet Filter (BPF)
Solana utilise LLVM (Low Level Virtual Machine) pour compiler les 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 buffer
- Fermer un programme ou buffer
- 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 dans 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 également 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 la 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 essentielles pour le réseau. Historiquement, ils étaient appelés programmes "natifs" et étaient distribués avec le code du validateur.
Programme | ID du programme | Description | Instructions |
---|---|---|---|
Programme système | 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 Programme système et paie les frais de transaction. | SystemInstruction |
Programme de vote | Vote111111111111111111111111111111111111111 | Crée et gère des comptes qui suivent l'état de vote du validateur 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 validateurs. | 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 ElGamal. | — |
Is this page helpful?