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 :

ChargeurID du programmeNotesLien vers les instructions
nativeNativeLoader1111111111111111111111111111111Possède les quatre autres chargeurs
v1BPFLoader1111111111111111111111111111111111Les instructions de gestion sont désactivées, mais les programmes s'exécutent toujours
v2BPFLoader2111111111111111111111111111111111Les instructions de gestion sont désactivées, mais les programmes s'exécutent toujoursInstructions
v3BPFLoaderUpgradeab1e11111111111111111111111Est en cours d'élimination progressiveInstructions
v4LoaderV411111111111111111111111111111111111v4 devrait devenir le chargeur standardInstructions

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

ProgrammeID du programmeDescriptionInstructions
Programme Ed25519Ed25519SigVerify111111111111111111111111111Vé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.

Ed25519SignatureOffsets
struct Ed25519SignatureOffsets {
signature_offset: u16, // offset to ed25519 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to public key of 32 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_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().instructions
instruction_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

ProgrammeID du programmeDescriptionInstructions
Programme Secp256k1KeccakSecp256k11111111111111111111111111111Vé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 :

Secp256k1SignatureOffsets
struct Secp256k1SignatureOffsets {
secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytes
secp_signature_instruction_index: u8, // instruction index to find signature
secp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytes
secp_pubkey_instruction_index: u8, // instruction index to find pubkey
secp_message_data_offset: u16, // offset to start of message data
secp_message_data_size: u16, // size of message data
secp_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().instructions
signature = 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

ProgrammeID du programmeDescriptionInstructions
Programme Secp256r1Secp256r1SigVerify1111111111111111111111111Vé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 :

Secp256r1SignatureOffsets
struct Secp256r1SignatureOffsets {
signature_offset: u16, // offset to compact secp256r1 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to compressed public key of 33 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_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 usize
if num_signatures == 0 || num_signatures > 8 {
return Error
}
expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START
if 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.

ProgrammeID du programmeDescriptionInstructions
Programme système11111111111111111111111111111111Cré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 voteVote111111111111111111111111111111111111111Crée et gère des comptes qui suivent l'état de vote du validateur et les récompenses.VoteInstruction
Programme de stakeStake11111111111111111111111111111111111111Crée et gère des comptes représentant les stakes et les récompenses pour les délégations aux validateurs.StakeInstruction
Programme de configurationConfig1111111111111111111111111111111111111Ajoute 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 calculComputeBudget111111111111111111111111111111Dé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'adressesAddressLookupTab1e1111111111111111111111111Gè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 ElGamalZkE1Gama1Proof11111111111111111111111111111Fournit une vérification de preuve à connaissance nulle pour les données chiffrées ElGamal.

Is this page helpful?

Table des matières

Modifier la page