1. Einleitung
Solana ist ein leistungsstarkes, erlaubnisfreies Layer-1-Blockchain-System, das die Entwicklung von Programmen (Smart Contracts) in verschiedenen Sprachen (z. B. Rust, C++ und C) unterstützt. Mithilfe von Tower BFT (Byzantine Fault Tolerant) kann es Tausende von Transaktionen pro Sekunde mit kurzen Blockzeiten verarbeiten. Eine der Kerninnovationen von Solana ist Proof of History (PoH), eine global verfügbare, erlaubnisfreie Zeitquelle im Netzwerk, die vor dem Konsens arbeitet. Wir werden PoH in Zukunft ausführlicher besprechen.
2. Unsere Mission
BlockSec ist ein Blockchain-Sicherheitsunternehmen, dessen Mission es ist, "das DApp-Ökosystem zu sichern". Daher bieten wir nicht nur Audits für Smart Contracts an, sondern auch Vorschläge zur sicheren Entwicklung von Smart Contracts für die gesamte Community. Angesichts der Popularität, der hohen Leistung und des großartigen Designs von Solana konzentriert sich diese Serie auf die Sicherheit von Smart Contracts in Rust auf Solana.
3. Hallo Solana
Bevor wir die Solana Smart Contracts aus der Perspektive der Sicherheit diskutieren, müssen wir zunächst wissen, wie man Solana Smart Contracts schreibt, kompiliert und bereitstellt. Hier verwenden wir Hello World als illustratives Beispiel.
3.1 Code-Überprüfung
In Solana wird ein Smart Contract als Programm bezeichnet. Das Hello World Programm zielt darauf ab, einen Zähler zu verwalten, der die Anzahl der Aufrufe des Zielkontos (im Besitz des Programms) durch den Client aufzeichnet und diese Zahl ausgibt.
Lassen Sie uns nun den gesamten Vertrag durchgehen.

Zeile 1 bis Zeile 9 bringen mithilfe des Schlüsselworts use viele Bibliotheken explizit in den Geltungsbereich.

In Zeile 12 wird [derive(BorshSerialize, BorshDeserialize, Debug)] verwendet, um Parameter zu serialisieren und zu deserialisieren, die an die Struktur GreetingAccount übergeben werden, die von Zeile 13 bis Zeile 1 Unterhalb von 16 definiert ist. Die Struktur enthält ein öffentliches Mitglied namens counter vom Typ u32. Danach, wie kommentiert, exportiert Zeile 19 den Einstiegspunkt des Programms, die Funktion process_instruction.

Die Funktion process_instruction akzeptiert drei Parameter (d. h. program_id, accounts und _instruction_data). Beachten Sie, dass program_id der öffentliche Schlüssel (d. h. die Adresse) des bereitgestellten Programms ist, während accounts das Konto enthält, zu dem "Hallo" gesagt werden soll. _instruction_data ist leer und wird nicht verwendet.
Um mehr über Programme und Konten in Solana zu erfahren, siehe Solana-Dokumentation.
In Zeile 27 wird eine Hallo-Nachricht ausgegeben. Von Zeile 30 bis Zeile 33 werden die Konten durchlaufen und das spezifische Konto, zu dem "Hallo" gesagt werden soll, extrahiert. Danach wird der Eigentümer des Kontos überprüft und muss mit der program_id übereinstimmen, um sicherzustellen, dass das Programm in das Konto schreiben kann. Schließlich wird das greeting_account mit try_from_slice extrahiert und der Zähler um 1 erhöht.
3.2 Programm kompilieren
Um das Programm zu kompilieren, müssen wir die Solana CLI mit dem folgenden Befehl installieren.
sh -c "$(curl -sSfL https://release.solana.com/v1.9.9/install)"
Um zu bestätigen, dass die Solana CLI erfolgreich installiert wurde, können wir ihre Version mit dem folgenden Befehl überprüfen.
solana --version
Beachten Sie, dass auch Rust und NodeJS erforderlich sind.
Um das Programm zu kompilieren, können wir den folgenden Befehl verwenden.
cargo build-bpf --manifest-path=./src/program-rust/Cargo.toml --bpf-out-dir=dist/program
Das kompilierte Programm wird im mit --bpf-out-dir angegebenen Verzeichnis generiert und heißt helloworld.so.
3.3 Vertrag bereitstellen
Um das kompilierte Programm auf Solana bereitzustellen, müssen wir zuerst einen Cluster auswählen. In Solana gibt es vier verschiedene Cluster: mainnet, testnet, devnet und localnet. In diesem Beitrag stellen wir das kompilierte Programm nur zu Demonstrationszwecken auf devnet bereit.
Wir verwenden den folgenden Befehl, um den Cluster festzulegen.
solana config set --url https://api.devnet.solana.com
Danach müssen wir die Wallet für die Bereitstellung generieren. solana-keygen new --force hilft bei der Generierung der Wallet. Weitere Informationen finden Sie in der Solana-Dokumentation.
Da das neu erstellte Konto kein Guthaben hat, um die Transaktionsgebühren zu bezahlen, senden wir mit dem folgenden Befehl 1 SOL per Airdrop.
solana airdrop 1 <IhrePublicKey> --url https://api.devnet.solana.com
Jetzt sind wir bereit, den Vertrag bereitzustellen.
solana program deploy dist/program/helloworld.so
Benutzer können die Programme und Transaktionen im Devnet Explorer überprüfen. In dieser Demo finden Sie das bereitgestellte Programm unter diesem Link.
3.4 Transaktion senden
Es wird empfohlen, Skripte, die als Client bezeichnet werden, zum Senden von Transaktionen in Solana zu schreiben. Glücklicherweise bietet Solana den Beispielcode. Um den Client auszuführen, müssen wir zuerst die Client-Abhängigkeiten installieren.
npm install
Nach Abschluss der Installation führen wir die main-Funktion in der Datei main.ts mit dem folgenden Befehl aus.
npm run start

In der Funktion main stellt der Client zunächst die Verbindung zum angegebenen Cluster (d. h. Devnet) mit der Funktion establishConnection() her, prüft den Zahler, der die Transaktionsgebühren zahlt, mit der Funktion establishPayer und validiert die Existenz des Programms und des Kontos, zu dem "Hallo" gesagt werden soll, mit der Funktion checkProgram. Beachten Sie, dass, wenn das erforderliche Konto nicht existiert, es durch Senden einer Transaktion erstellt wird. In unserer Demonstration wird das Konto in dieser Transaktion erstellt.

Wenn alles bereit ist, wird die Funktion sayHello aufgerufen, um dem Zielkonto "Hallo" zu sagen. Die Transaktion besteht aus einer Anweisung. Diese Anweisung empfängt keys, die ein Konto enthalten. Der öffentliche Schlüssel des Kontos (d. h. greetedPubkey) ist das Zielkonto, zu dem "Hallo" gesagt werden soll. Beachten Sie, dass dieses Konto für die Speicherung verwendet wird und kein Signierer ist. In diesem Fall ist das Attribut isSigner false, während isWritable true ist. Der programId ist der Eigentümer der greetedPubkey und auch die Adresse des bereitgestellten Vertrags. Beachten Sie, dass data leer ist und in dieser Transaktion nicht verwendet wird. In Zeile 208 wird die Funktion sendAndConfirmTransaction aufgerufen, und die Transaktion wird an den Cluster gesendet.
Sie können die detaillierte Transaktion hier anzeigen.
4. Schlussfolgerung
In diesem Artikel haben wir kurz den Hintergrund von Solana vorgestellt und das Beispielprojekt (d. h. Hello World) durchlaufen. Wir haben gelernt, wie man ein Programm auf Solana bereitstellt und wie man den Client verwendet, um mit dem On-Chain-Programm zu interagieren. Bitte folgen Sie weiterhin unserem Blog, wir werden in dieser Serie konsequent weitere Artikel veröffentlichen.
Andere Artikel in dieser Serie lesen:
- Sichern Sie das Solana-Ökosystem (2) — Aufrufe zwischen Programmen
- Sichern Sie das Solana-Ökosystem (3) — Programm-Upgrade
- Sichern Sie das Solana-Ökosystem (4) — Kontenvalidierung
- Sichern Sie das Solana-Ökosystem (5) — Multi-Sig
- Sichern Sie das Solana-Ökosystem (6) — Multi-Sig2
- Sichern Sie das Solana-Ökosystem (7) — Typenverwechslung



