Programmi

Su Solana, gli "smart contract" sono chiamati programmi. I programmi vengono distribuiti sulla blockchain in account che contengono il file binario eseguibile compilato del programma. Gli utenti interagiscono con i programmi inviando transazioni contenenti istruzioni che indicano al programma cosa fare.

Punti chiave

  • I programmi sono account contenenti codice eseguibile, organizzato in funzioni chiamate istruzioni.
  • Mentre i programmi sono stateless, possono includere istruzioni che creano e aggiornano altri account per memorizzare dati.
  • Un'autorità di aggiornamento può aggiornare i programmi. Una volta rimossa questa autorità, il programma diventa immutabile.
  • Gli utenti possono verificare che i dati di un account di programma on-chain corrispondano al suo codice sorgente pubblico attraverso build verificabili.

Scrivere programmi Solana

I programmi Solana sono prevalentemente scritti nel linguaggio di programmazione Rust, con due approcci comuni per lo sviluppo:

  • Anchor: Un framework progettato per lo sviluppo di programmi Solana. Offre un modo più veloce e semplice per scrivere programmi, utilizzando macro Rust per ridurre il codice ripetitivo. Per i principianti, si consiglia di iniziare con il framework Anchor.

  • Rust nativo: Questo approccio implica la scrittura di programmi Solana in Rust senza utilizzare framework. Offre maggiore flessibilità ma comporta una maggiore complessità.

Aggiornare programmi Solana

Per saperne di più sul deployment e l'aggiornamento dei programmi, consulta la pagina deploying programs.

I programmi possono essere modificati direttamente da un account designato come "autorità di aggiornamento", che è tipicamente l'account che ha originariamente distribuito il programma. Se l'autorità di aggiornamento viene revocata e impostata su None, il programma diventa immutabile e non può più essere aggiornato.

Programmi verificabili

Le build verificabili permettono a chiunque di controllare se il codice on-chain di un programma corrisponde al suo codice sorgente pubblico, rendendo possibile rilevare discrepanze tra la versione sorgente e quella distribuita.

La community degli sviluppatori Solana ha introdotto strumenti per supportare le build verificabili, consentendo sia agli sviluppatori che agli utenti di verificare che i programmi on-chain riflettano accuratamente il loro codice sorgente condiviso pubblicamente.

  • Ricerca di programmi verificati: Per controllare rapidamente i programmi verificati, gli utenti possono cercare l'indirizzo di un programma su Solana Explorer. Visualizza un esempio di programma verificato qui.

  • Strumenti di verifica: La Solana Verifiable Build CLI di Ellipsis Labs consente agli utenti di verificare indipendentemente i programmi on-chain rispetto al codice sorgente pubblicato.

  • Supporto per build verificabili in Anchor: Anchor fornisce supporto integrato per build verificabili. I dettagli sono disponibili nella documentazione di Anchor.

Berkeley Packet Filter (BPF)

Solana utilizza LLVM (Low Level Virtual Machine) per compilare i programmi in file ELF (Executable and Linkable Format). Questi file contengono la versione personalizzata di Solana del bytecode eBPF, chiamato "Solana Bytecode Format" (sBPF). Il file ELF contiene il binario del programma e viene memorizzato on-chain in un account eseguibile quando il programma viene distribuito.

Programmi integrati

Programmi loader

Ogni programma è di proprietà di un altro programma, che è il suo loader. Attualmente, esistono cinque programmi loader:

LoaderProgram IDNoteLink alle istruzioni
nativeNativeLoader1111111111111111111111111111111Possiede gli altri quattro loader
v1BPFLoader1111111111111111111111111111111111Le istruzioni di gestione sono disabilitate, ma i programmi vengono ancora eseguiti
v2BPFLoader2111111111111111111111111111111111Le istruzioni di gestione sono disabilitate, ma i programmi vengono ancora eseguitiIstruzioni
v3BPFLoaderUpgradeab1e11111111111111111111111È in fase di eliminazioneIstruzioni
v4LoaderV411111111111111111111111111111111111Si prevede che v4 diventi il loader standardIstruzioni

Questi loader sono necessari per creare e gestire programmi personalizzati:

  • Distribuire un nuovo programma o buffer
  • Chiudere un programma o buffer
  • Ridistribuire / aggiornare un programma esistente
  • Trasferire l'autorità su un programma
  • Finalizzare un programma

Loader-v3 e loader-v4 supportano modifiche ai programmi dopo la loro distribuzione iniziale. Il permesso di farlo è regolato dall'autorità di un programma poiché la proprietà dell'account di ciascun programma risiede nel loader.

Programmi precompilati

Programma Ed25519

ProgrammaID ProgrammaDescrizioneIstruzioni
Programma Ed25519Ed25519SigVerify111111111111111111111111111Verifica le firme ed25519. Se una firma fallisce, viene restituito un errore.Istruzioni

Il programma ed25519 elabora un'istruzione. Il primo u8 è un conteggio del numero di firme da controllare, seguito da un singolo byte di padding. Dopo di che, la seguente struttura viene serializzata, una per ogni firma da controllare.

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
}

Lo pseudocodice della verifica della firma:

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
}

Programma Secp256k1

ProgrammaID ProgrammaDescrizioneIstruzioni
Programma Secp256k1KeccakSecp256k11111111111111111111111111111Verifica le operazioni di recupero della chiave pubblica secp256k1 (ecrecover).Istruzioni

Il programma secp256k1 elabora un'istruzione che prende come primo byte un conteggio della seguente struttura serializzata nei dati dell'istruzione:

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
}

Lo pseudocodice della verifica del recupero:

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
}

Questo permette all'utente di specificare qualsiasi dato di istruzione nella transazione per i dati di firma e messaggio. Specificando una sysvar di istruzioni speciale, si possono anche 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.

Programma Secp256r1

ProgrammaID ProgrammaDescrizioneIstruzioni
Programma Secp256r1Secp256r1SigVerify1111111111111111111111111Verifica 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 è un conteggio del numero di firme da controllare, seguito da un singolo byte di padding. Dopo di che, la seguente struttura viene serializzata, una per ogni firma da controllare:

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
}

Lo pseudocodice della verifica della firma:

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
}

Nota: i valori S bassi sono imposti per tutte le firme per evitare la malleabilità accidentale della firma.

Programmi Core

La genesi del cluster Solana include un elenco di programmi speciali che forniscono funzionalità core per la rete. Storicamente questi erano chiamati programmi "nativi" e venivano distribuiti insieme al codice del validator.

ProgrammaID ProgrammaDescrizioneIstruzioni
System Program11111111111111111111111111111111Crea 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
Programma di VotoVote111111111111111111111111111111111111111Crea e gestisce account che tengono traccia dello stato di voto del validator e delle ricompense.VoteInstruction
Programma di StakeStake11111111111111111111111111111111111111Crea e gestisce account che rappresentano lo stake e le ricompense per le deleghe ai validator.StakeInstruction
Programma di ConfigurazioneConfig1111111111111111111111111111111111111Aggiunge 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 i dati da memorizzare al suo interno.ConfigInstruction
Programma di Budget di CalcoloComputeBudget111111111111111111111111111111Imposta 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
Programma di Tabella di Ricerca IndirizziAddressLookupTab1e1111111111111111111111111Gestisce 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
Programma di Prova ZK ElGamalZkE1Gama1Proof11111111111111111111111111111Fornisce la verifica della prova a conoscenza zero per i dati crittografati con ElGamal.

Is this page helpful?

Indice

Modifica Pagina