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:

LoaderProgramm-IDHinweiseAnweisungen-Link
nativeNativeLoader1111111111111111111111111111111Besitzt die anderen vier Loader
v1BPFLoader1111111111111111111111111111111111Verwaltungs-Anweisungen sind deaktiviert, aber Programme werden weiterhin ausgeführt
v2BPFLoader2111111111111111111111111111111111Verwaltungs-Anweisungen sind deaktiviert, aber Programme werden weiterhin ausgeführtAnweisungen
v3BPFLoaderUpgradeab1e11111111111111111111111Wird schrittweise eingestelltAnweisungen
v4LoaderV411111111111111111111111111111111111v4 wird voraussichtlich zum Standard-LoaderAnweisungen

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

ProgrammProgramm-IDBeschreibungAnweisungen
Ed25519-ProgrammEd25519SigVerify111111111111111111111111111Verifiziert 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.

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
}

Der Pseudocode der Signaturverifizierung:

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
}

Secp256k1-Programm

ProgrammProgramm-IDBeschreibungAnweisungen
Secp256k1-ProgrammKeccakSecp256k11111111111111111111111111111Verifiziert 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:

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
}

Der Pseudocode der Recovery-Verifizierung:

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
}

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

ProgrammProgramm-IDBeschreibungAnweisungen
Secp256r1-ProgrammSecp256r1SigVerify1111111111111111111111111Verifiziert 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:

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
}

Der Pseudocode der Signaturverifizierung:

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
}

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.

ProgrammProgramm-IDBeschreibungAnweisungen
System-Programm11111111111111111111111111111111Erstellt neue Konten, weist Kontendaten zu, ordnet Konten besitzenden Programmen zu, überträgt Lamports von System-Programm-eigenen Konten und zahlt Transaktionsgebühren.SystemInstruction
Vote-ProgrammVote111111111111111111111111111111111111111Erstellt und verwaltet Konten, die den Validator-Abstimmungsstatus und Belohnungen verfolgen.VoteInstruction
Stake-ProgrammStake11111111111111111111111111111111111111Erstellt und verwaltet Konten, die Einsätze und Belohnungen für Delegationen an Validatoren darstellen.StakeInstruction
Config-ProgrammConfig1111111111111111111111111111111111111Fü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-ProgrammComputeBudget111111111111111111111111111111Legt Recheneinheitslimits und Preise für Transaktionen fest, sodass Benutzer Rechenressourcen und Priorisierungsgebühren kontrollieren können.ComputeBudgetInstruction
Address Lookup Table-ProgrammAddressLookupTab1e1111111111111111111111111Verwaltet Adressnachschlagetabellen, die es Transaktionen ermöglichen, mehr Konten zu referenzieren, als sonst in die Kontenliste der Transaktion passen würden.ProgramInstruction
ZK ElGamal Proof-ProgrammZkE1Gama1Proof11111111111111111111111111111Bietet Zero-Knowledge-Proof-Verifizierung für ElGamal-verschlüsselte Daten.

Is this page helpful?

Inhaltsverzeichnis

Seite bearbeiten