Programme
Auf Solana werden "Smart Contracts" als Programme bezeichnet. Programme werden on-chain in Konten bereitgestellt, die den kompilierten ausführbaren Binärcode des Programms enthalten. Benutzer interagieren mit Programmen, indem sie Transaktionen mit Anweisungen senden, die dem Programm mitteilen, was zu tun ist.
Wichtige Punkte
- Programme sind Konten, die ausführbaren Code enthalten, der in Funktionen organisiert ist, die als Anweisungen bezeichnet werden.
- Während Programme zustandslos sind, können sie Anweisungen enthalten, die andere Konten erstellen und aktualisieren, um Daten zu speichern.
- Eine Upgrade-Authority kann Programme aktualisieren. Sobald diese Berechtigung entfernt wird, wird das Programm unveränderlich.
- Benutzer können überprüfen, ob die Daten eines On-Chain-Programmkontos mit seinem öffentlichen Quellcode übereinstimmen, durch verifizierbare Builds.
Solana-Programme schreiben
Solana-Programme werden überwiegend in der Rust-Programmiersprache geschrieben, wobei zwei gängige Ansätze für die Entwicklung existieren:
-
Anchor: Ein Framework für die Entwicklung von Solana- Programmen. Es bietet eine schnellere und einfachere Möglichkeit, Programme zu schreiben, indem es Rust-Makros verwendet, um Boilerplate-Code zu reduzieren. Für Anfänger wird empfohlen, mit dem Anchor-Framework zu beginnen.
-
Native Rust: Dieser Ansatz beinhaltet das Schreiben von Solana- Programmen in Rust ohne die Nutzung von Frameworks. Er bietet mehr Flexibilität, ist aber mit erhöhter Komplexität verbunden.
Aktualisieren von Solana-Programmen
Um mehr über das Deployment und Upgraden von Programmen zu erfahren, siehe die Programme deployen-Seite.
Programme können
direkt modifiziert
werden durch ein Konto, das als "Upgrade-Authority" bezeichnet wird, was
typischerweise das Konto ist, das ursprünglich das Programm deployed hat. Wenn
die
Upgrade-Authority
widerrufen und auf None
gesetzt wird, wird das Programm unveränderlich und
kann nicht mehr aktualisiert werden.
Verifizierbare Programme
Verifizierbare Builds ermöglichen es jedem, zu überprüfen, ob der On-Chain-Code eines Programms mit seinem öffentlichen Quellcode übereinstimmt, wodurch Diskrepanzen zwischen Quell- und bereitgestellten Versionen erkannt werden können.
Die Solana-Entwicklergemeinschaft hat Tools zur Unterstützung verifizierbarer Builds eingeführt, die es sowohl Entwicklern als auch Nutzern ermöglichen zu überprüfen, ob On-Chain-Programme ihren öffentlich geteilten Quellcode korrekt widerspiegeln.
-
Suche nach verifizierten Programmen: Um schnell nach verifizierten Programmen zu suchen, können Nutzer im Solana Explorer nach einer Programmadresse suchen. Ein Beispiel für ein verifiziertes Programm finden Sie hier.
-
Verifizierungstools: Die Solana Verifiable Build CLI von Ellipsis Labs ermöglicht es Nutzern, On-Chain-Programme unabhängig gegen veröffentlichten Quellcode zu verifizieren.
-
Unterstützung für verifizierbare Builds in Anchor: Anchor bietet integrierte Unterstützung für verifizierbare Builds. Details finden Sie in der Anchor-Dokumentation.
Berkeley Packet Filter (BPF)
Solana verwendet LLVM (Low Level Virtual Machine), um Programme in ELF (Executable and Linkable Format) Dateien zu kompilieren. Diese Dateien enthalten Solanas angepasste Version des eBPF Bytecodes, genannt "Solana Bytecode Format" (sBPF). Die ELF-Datei enthält das Programm-Binary und wird bei der Bereitstellung des Programms on-chain in einem ausführbaren Konto gespeichert.
Integrierte Programme
Loader-Programme
Jedes Programm selbst gehört einem anderen Programm, seinem Loader. Derzeit existieren fünf Loader-Programme:
Loader | Programm-ID | Hinweise | Anweisungen-Link |
---|---|---|---|
native | NativeLoader1111111111111111111111111111111 | Besitzt die anderen vier Loader | — |
v1 | BPFLoader1111111111111111111111111111111111 | Verwaltungs-Anweisungen sind deaktiviert, aber Programme werden weiterhin ausgeführt | — |
v2 | BPFLoader2111111111111111111111111111111111 | Verwaltungs-Anweisungen sind deaktiviert, aber Programme werden weiterhin ausgeführt | Anweisungen |
v3 | BPFLoaderUpgradeab1e11111111111111111111111 | Wird schrittweise eingestellt | Anweisungen |
v4 | LoaderV411111111111111111111111111111111111 | v4 wird voraussichtlich zum Standard-Loader | Anweisungen |
Diese Loader sind notwendig, um benutzerdefinierte Programme zu erstellen und zu verwalten:
- Deployment eines neuen Programms oder Puffers
- Schließen eines Programms oder Puffers
- Erneutes Deployment / Upgrade eines bestehenden Programms
- Übertragung der Autorität über ein Programm
- Finalisierung eines Programms
Loader-v3 und loader-v4 unterstützen Änderungen an Programmen nach ihrem ersten Deployment. Die Berechtigung dazu wird durch die Autorität eines Programms geregelt, da die Konteneigentümerschaft jedes Programms beim Loader liegt.
Vorkompilierte Programme
Ed25519-Programm
Programm | Programm-ID | Beschreibung | Anweisungen |
---|---|---|---|
Ed25519-Programm | Ed25519SigVerify111111111111111111111111111 | Verifiziert ed25519-Signaturen. Wenn eine Signatur fehlschlägt, wird ein Fehler zurückgegeben. | Anweisungen |
Das ed25519-Programm verarbeitet eine Anweisung. Das erste u8
ist ein Zähler
für die Anzahl der zu prüfenden Signaturen, gefolgt von einem einzelnen Byte
Padding. Danach wird die folgende Struktur serialisiert, eine für jede zu
prüfende Signatur.
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}
Der Pseudocode der Signaturverifizierung:
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}
Secp256k1-Programm
Programm | Programm-ID | Beschreibung | Anweisungen |
---|---|---|---|
Secp256k1-Programm | KeccakSecp256k11111111111111111111111111111 | Verifiziert secp256k1 Public-Key-Recovery-Operationen (ecrecover). | Anweisungen |
Das secp256k1-Programm verarbeitet eine Anweisung, die als erstes Byte einen Zähler für die folgende in den Anweisungsdaten serialisierte Struktur enthält:
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}
Der Pseudocode der Recovery-Verifizierung:
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}
Dies ermöglicht dem Benutzer, beliebige Anweisungsdaten in der Transaktion für Signatur- und Nachrichtendaten anzugeben. Durch Angabe einer speziellen Instructions-Sysvar kann man auch Daten aus der Transaktion selbst empfangen.
Die Kosten der Transaktion werden anhand der Anzahl der zu verifizierenden Signaturen multipliziert mit dem Signaturkosten-Verifizierungsmultiplikator berechnet.
Secp256r1-Programm
Programm | Programm-ID | Beschreibung | Anweisungen |
---|---|---|---|
Secp256r1-Programm | Secp256r1SigVerify1111111111111111111111111 | Verifiziert bis zu 8 secp256r1-Signaturen. Nimmt eine Signatur, einen öffentlichen Schlüssel und eine Nachricht entgegen. Gibt einen Fehler zurück, wenn eine fehlschlägt. | Anweisungen |
Das secp256r1-Programm verarbeitet eine Anweisung. Das erste u8
ist eine
Anzahl der zu prüfenden Signaturen, gefolgt von einem einzelnen Byte Padding.
Danach wird die folgende Struktur serialisiert, eine für jede zu prüfende
Signatur:
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}
Der Pseudocode der Signaturverifizierung:
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}
Hinweis: Niedrige S-Werte werden für alle Signaturen erzwungen, um versehentliche Signatur-Manipulierbarkeit zu vermeiden.
Kernprogramme
Die Solana-Cluster-Genesis enthält eine Liste spezieller Programme, die Kernfunktionalitäten für das Netzwerk bereitstellen. Historisch wurden diese als "native" Programme bezeichnet und wurden zusammen mit dem Validator-Code verteilt.
Programm | Programm-ID | Beschreibung | Anweisungen |
---|---|---|---|
System-Programm | 11111111111111111111111111111111 | Erstellt neue Konten, weist Kontendaten zu, ordnet Konten besitzenden Programmen zu, überträgt Lamports von System-Programm-eigenen Konten und zahlt Transaktionsgebühren. | SystemInstruction |
Vote-Programm | Vote111111111111111111111111111111111111111 | Erstellt und verwaltet Konten, die den Validator-Abstimmungsstatus und Belohnungen verfolgen. | VoteInstruction |
Stake-Programm | Stake11111111111111111111111111111111111111 | Erstellt und verwaltet Konten, die Einsätze und Belohnungen für Delegationen an Validatoren darstellen. | StakeInstruction |
Config-Programm | Config1111111111111111111111111111111111111 | Fügt Konfigurationsdaten zur Chain hinzu, gefolgt von der Liste der öffentlichen Schlüssel, die zu deren Änderung berechtigt sind. Im Gegensatz zu anderen Programmen definiert das Config-Programm keine einzelnen Anweisungen. Es hat nur eine implizite Anweisung: "store". Seine instruction data ist ein Satz von Schlüsseln, die den Zugriff auf das Konto und die darin zu speichernden Daten steuern. | ConfigInstruction |
Compute Budget-Programm | ComputeBudget111111111111111111111111111111 | Legt Recheneinheitslimits und Preise für Transaktionen fest, sodass Benutzer Rechenressourcen und Priorisierungsgebühren kontrollieren können. | ComputeBudgetInstruction |
Address Lookup Table-Programm | AddressLookupTab1e1111111111111111111111111 | Verwaltet Adressnachschlagetabellen, die es Transaktionen ermöglichen, mehr Konten zu referenzieren, als sonst in die Kontenliste der Transaktion passen würden. | ProgramInstruction |
ZK ElGamal Proof-Programm | ZkE1Gama1Proof11111111111111111111111111111 | Bietet Zero-Knowledge-Proof-Verifizierung für ElGamal-verschlüsselte Daten. | — |
Is this page helpful?