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 deployato, Solana utilizza LLVM per compilarlo in formato eseguibile e linkabile (ELF). Il file ELF contiene il binario del programma in Solana Bytecode Format (sBPF) ed è salvato on-chain in un account eseguibile.
sBPF è la versione personalizzata di Solana del bytecode eBPF.
Scrivere programmi
La maggior parte dei programmi è scritta in Rust, con due approcci di sviluppo comuni:
- Anchor: Anchor è un framework progettato per uno sviluppo Solana veloce e semplice. Utilizza macro Rust per ridurre il codice boilerplate, rendendolo ideale per i principianti.
- Rust nativo: scrivi programmi in Rust senza utilizzare alcun framework. Questo approccio offre maggiore flessibilità ma comporta una complessità aumentata.
Aggiornare programmi
Per
modificare
un programma esistente, un account deve essere designato come
upgrade authority.
(Tipicamente lo stesso account che ha originariamente
deployato il programma.) Se l'upgrade authority
viene revocata e impostata su None, il programma non può più essere
aggiornato.
Verificare programmi
Solana supporta le build verificabili, che consentono agli utenti di verificare 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 verificare se un programma esistente è verificato, cerca il suo ID programma su Solana Explorer. In alternativa, puoi utilizzare la Solana Verifiable Build CLI di Ellipsis Labs per verificare in modo indipendente i programmi on-chain.
Programmi integrati
Il System Program
Il System Program è l'unico account in grado di creare nuovi account. Per impostazione predefinita, tutti i nuovi account sono di proprietà del System Program, anche se molti vengono assegnati a un nuovo proprietario al momento della creazione. Il System Program esegue 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 account di programma diverso. È così che i programmi personalizzati acquisiscono la proprietà 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.
Attualmente esistono cinque programmi loader, come mostrato nella tabella seguente.
| Loader | ID programma | Note | Link istruzioni |
|---|---|---|---|
| native | NativeLoader1111111111111111111111111111111 | Possiede gli altri quattro loader | — |
| v1 | BPFLoader1111111111111111111111111111111111 | Le istruzioni di gestione sono disabilitate, ma i programmi vengono comunque eseguiti | — |
| v2 | BPFLoader2111111111111111111111111111111111 | Le istruzioni di gestione sono disabilitate, ma i programmi vengono comunque 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 fase di 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.
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}
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.
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}
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 | Program ID | Descrizione | Istruzioni |
|---|---|---|---|
| Programma Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Verifica fino a 8 firme secp256r1. Accetta una firma, una chiave pubblica e un messaggio. Restituisce un errore se una qualsiasi 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.
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.
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 | Program ID | Descrizione | Istruzioni |
|---|---|---|---|
| System | 11111111111111111111111111111111 | Crea nuovi account, alloca dati dell'account, assegna account ai programmi proprietari, trasferisce lamport da account di proprietà del programma System e paga le commissioni di transazione | SystemInstruction |
| Vote | Vote111111111111111111111111111111111111111 | Crea e gestisce account che tracciano lo stato di voto del validatore e le ricompense | VoteInstruction |
| Stake | Stake11111111111111111111111111111111111111 | Crea e gestisce account che rappresentano lo stake e le ricompense per le deleghe ai validatori | 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 memorizzati al suo interno | ConfigInstruction |
| Compute Budget | ComputeBudget111111111111111111111111111111 | Imposta limiti e prezzi delle unità di calcolo per le transazioni, consentendo agli utenti di controllare le risorse di calcolo e le commissioni di prioritizzazione | ComputeBudgetInstruction |
| Address Lookup Table | AddressLookupTab1e1111111111111111111111111 | Gestisce le tabelle di ricerca degli indirizzi, che consentono alle transazioni di fare riferimento a più account di quanti potrebbero altrimenti rientrare nell'elenco degli account della transazione | ProgramInstruction |
| ZK ElGamal Proof | ZkE1Gama1Proof11111111111111111111111111111 | Fornisce la verifica delle prove a conoscenza zero per i dati crittografati con ElGamal | — |
Is this page helpful?