Programmi
Su Solana, uno smart contract è chiamato programma. Un programma è un account stateless che contiene codice eseguibile. Questo codice è organizzato in funzioni chiamate istruzioni. Gli utenti interagiscono con un programma inviando una transazione contenente una o più istruzioni. Una transazione può includere istruzioni da più programmi.
Quando un programma viene distribuito, Solana utilizza LLVM per compilarlo in formato eseguibile e collegabile (ELF). Il file ELF contiene il binario del programma in Solana Bytecode Format (sBPF) e viene salvato on-chain in un account eseguibile.
sBPF è la versione personalizzata di Solana del bytecode eBPF.
Scrivere programmi
La maggior parte dei programmi sono scritti in Rust, con due approcci comuni di sviluppo:
- Anchor: Anchor è un framework progettato per uno sviluppo rapido e semplice su Solana. Utilizza macro di Rust per ridurre il codice boilerplate—rendendolo ottimo per i principianti.
- Rust nativo: Scrivi programmi in Rust senza utilizzare alcun framework. Questo approccio offre maggiore flessibilità ma comporta una maggiore complessità.
Aggiornare programmi
Per modificare un programma esistente, un account deve essere designato come autorità di aggiornamento. (Tipicamente lo stesso account che ha originariamente distribuito il programma.) Se l'autorità di aggiornamento viene revocata e impostata su null, il programma non può più essere aggiornato.
Verificare programmi
Solana supporta build verificabili, che permettono agli utenti di controllare se il codice on-chain di un programma corrisponde al suo codice sorgente pubblico. Il framework Anchor fornisce supporto integrato per creare una build verificabile.
Per controllare se un programma esistente è verificato, cerca il suo ID programma su Solana Explorer. In alternativa, puoi utilizzare la CLI Solana Verifiable Build di Ellipsis Labs, per verificare indipendentemente i programmi on-chain.
Programmi integrati
Il System Program
Il System Program è l'unico account che può creare nuovi account. Per impostazione predefinita, tutti i nuovi account sono di proprietà del System Program, anche se a molti viene assegnato un nuovo proprietario al momento della creazione. Il System Program svolge le seguenti funzioni chiave:
| Funzione | Descrizione |
|---|---|
| Creazione di nuovi account | Solo il System Program può creare nuovi account. |
| Allocazione dello spazio | Imposta la capacità in byte per il campo dati di ciascun account. |
| Assegnazione della proprietà del programma | Una volta che il System Program crea un account, può riassegnare il proprietario del programma designato a un diverso program account. È così che i programmi personalizzati prendono possesso dei nuovi account creati dal System Program. |
| Trasferimento di SOL | Trasferisce lamport (SOL) dagli account di sistema ad altri account. |
L'indirizzo del System Program è 11111111111111111111111111111111.
Programmi loader
Ogni programma è di proprietà di un altro—il suo loader. I loader vengono utilizzati per distribuire, ridistribuire, aggiornare o chiudere i programmi. Vengono anche utilizzati per finalizzare un programma e trasferire l'autorità del programma.
I programmi loader sono talvolta chiamati 'BPF Loader'.
Attualmente ci sono cinque programmi loader, come mostrato nella tabella seguente.
| Loader | Program ID | Note | Link alle istruzioni |
|---|---|---|---|
| native | NativeLoader1111111111111111111111111111111 | Possiede gli altri quattro loader | — |
| v1 | BPFLoader1111111111111111111111111111111111 | Le istruzioni di gestione sono disabilitate, ma i programmi continuano a essere eseguiti | — |
| v2 | BPFLoader2111111111111111111111111111111111 | Le istruzioni di gestione sono disabilitate, ma i programmi continuano a essere eseguiti | Istruzioni |
| v3 | BPFLoaderUpgradeab1e11111111111111111111111 | I programmi possono essere aggiornati dopo la distribuzione. L'eseguibile del programma è memorizzato in un account dati del programma separato | Istruzioni |
| v4 | LoaderV411111111111111111111111111111111111 | In sviluppo (non rilasciato) | Istruzioni |
I programmi distribuiti con loader-v3 o loader-v4 possono essere modificabili dopo la distribuzione, come determinato dalla loro autorità di aggiornamento.
Quando viene distribuito un nuovo programma, verrà utilizzata per impostazione predefinita la versione più recente del loader.
Programmi precompilati
Oltre ai programmi loader, Solana fornisce i seguenti programmi precompilati.
Verifica firma ed25519
Il programma ed25519 viene utilizzato per verificare una o più firme ed25519.
| Programma | Program ID | Descrizione | Istruzioni |
|---|---|---|---|
| Programma Ed25519 | Ed25519SigVerify111111111111111111111111111 | Verifica le firme ed25519. Se una qualsiasi firma fallisce, viene restituito un errore. | Istruzioni |
Il programma ed25519 elabora un'istruzione. Il primo u8 dell'istruzione
contiene un conteggio del numero di firme da verificare, seguito da un singolo
byte di riempimento. Successivamente, la seguente struttura viene serializzata,
una per ogni firma da verificare.
Ed25519SignatureOffsets
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}
Signature verification pseudocode
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}
Verifica recupero secp256k1
Il programma secp256k1 viene utilizzato per verificare le operazioni di recupero della chiave pubblica secp256k1.
| Programma | Program ID | Descrizione | Istruzioni |
|---|---|---|---|
| Programma Secp256k1 | KeccakSecp256k11111111111111111111111111111 | Verifica le operazioni di recupero della chiave pubblica secp256k1 (ecrecover). | Istruzioni |
Il programma secp256k1 elabora un'istruzione. Il primo byte dell'istruzione contiene un conteggio del numero di chiavi pubbliche da verificare. Successivamente, la seguente struttura viene creata una volta per ogni chiave pubblica, quindi serializzata e aggiunta ai dati dell'istruzione.
Secp256k1SignatureOffsets
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}
Recovery verification pseudocode
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}
Questo consente all'utente di specificare qualsiasi dato di istruzione nella transazione per i dati di firma e messaggio. Specificando una sysvar di istruzioni speciale, è anche possibile ricevere dati dalla transazione stessa.
Il costo della transazione conterà il numero di firme da verificare moltiplicato per il moltiplicatore del costo di verifica della firma.
Il programma secp256r1 viene utilizzato per verificare fino a 8 firme secp256r1.
| Programma | ID del programma | Descrizione | Istruzioni |
|---|---|---|---|
| Programma Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Verifica fino a 8 firme secp256r1. Prende una firma, una chiave pubblica e un messaggio. Restituisce un errore se qualcuna fallisce. | Istruzioni |
Il programma secp256r1 elabora un'istruzione. Il primo u8 dell'istruzione è un
conteggio del numero di firme da verificare, seguito da un singolo byte di
riempimento. Successivamente, la seguente struttura viene creata per ogni firma,
quindi serializzata e aggiunta ai dati dell'istruzione.
Secp256r1SignatureOffsets
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}
I valori S bassi sono imposti per tutte le firme per evitare la malleabilità accidentale della firma.
Signature verification psuedocode
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}
Programmi core
I programmi nell'elenco seguente forniscono le funzionalità core della rete.
| Programma | ID del programma | Descrizione | Istruzioni |
|---|---|---|---|
| System | 11111111111111111111111111111111 | Crea nuovi account, alloca dati dell'account, assegna account ai programmi proprietari, trasferisce lamport dagli account di proprietà del System Program e paga le commissioni di transazione | SystemInstruction |
| Vote | Vote111111111111111111111111111111111111111 | Crea e gestisce account che tengono traccia dello stato di voto del validator e delle ricompense | VoteInstruction |
| Stake | Stake11111111111111111111111111111111111111 | Crea e gestisce account che rappresentano lo stake e le ricompense per le deleghe ai validator | StakeInstruction |
| Config | Config1111111111111111111111111111111111111 | Aggiunge dati di configurazione alla chain, seguiti dall'elenco delle chiavi pubbliche autorizzate a modificarli. A differenza degli altri programmi, il programma Config non definisce istruzioni individuali. Ha solo un'istruzione implicita: "store". I suoi dati di istruzione sono un insieme di chiavi che controllano l'accesso all'account e ai dati in esso memorizzati | ConfigInstruction |
| Compute Budget | ComputeBudget111111111111111111111111111111 | Imposta i limiti e i prezzi delle unità di calcolo per le transazioni, consentendo agli utenti di controllare le risorse di calcolo e le commissioni di priorità | ComputeBudgetInstruction |
| Address Lookup Table | AddressLookupTab1e1111111111111111111111111 | Gestisce le tabelle di ricerca degli indirizzi, che consentono alle transazioni di fare riferimento a più account di quanti ne potrebbero altrimenti contenere nell'elenco degli account della transazione | ProgramInstruction |
| ZK ElGamal Proof | ZkE1Gama1Proof11111111111111111111111111111 | Fornisce la verifica della prova a conoscenza zero per i dati crittografati con ElGamal | — |
Is this page helpful?