Geschrieben von: Sui Network

Sui ist eine öffentliche L1-Kette, die nach Grundprinzipien neu gestaltet und aufgebaut wurde, mit dem Ziel, Schöpfern und Entwicklern eine Entwicklungsplattform zur Verfügung zu stellen, die in der Lage ist, die nächste Milliarde Benutzer in Web3 zu hosten. Anwendungen auf Sui basieren auf der intelligenten Vertragssprache Move und sind horizontal skalierbar, sodass Entwickler eine breite Palette von Anwendungsentwicklungen schnell und kostengünstig unterstützen können. Das Sui-Mainnet wurde am 3. Mai 2023 offiziell gestartet.

Dieser Artikel dient Entwicklern als Kurzreferenz zu Best Practices im Sui Network.

Allgemeinwissen bewegen

Lesen Sie mehr über Paket-Upgrades und schreiben Sie upgrade-freundlichen Code.

Pakete sind unveränderlich und anfälliger Paketcode kann für immer aufgerufen werden. Die Lösung besteht darin, Schutz auf Objektebene hinzuzufügen. Wenn Sie ein Paket von P auf P' aktualisieren, verwenden andere Pakete und Clients, die von P abhängig sind, weiterhin P, anstatt automatisch auf P' zu aktualisieren. Daher muss Code, der sowohl vom Paket als auch vom Client abhängt, so aktualisiert werden, dass er explizit auf P' verweist. Pakete, von denen erwartet wird, dass sie durch abhängige Pakete erweitert werden, können verhindern, dass ihre vorherigen Erweiterungen bei jedem Upgrade beschädigt werden, indem sie eine (unveränderliche) Schnittstelle bereitstellen, die über alle Versionen hinweg dem Standard entspricht. Am Beispiel der Cross-Chain-Brücke von Wormhole werden Nachrichten über Wormhole als Brücke gesendet. Um ein Erweiterungspaket zum Senden von Nachrichten zu generieren, können Sie die Anweisung „prepare_message“ in jeder Version des Wormhole-Pakets verwenden, um ein MessageTicket und den Client zu generieren Code, der die Nachricht sendet, muss das MessageTicket an Publish_message im neuesten Versionspaket übergeben. Öffentliche Funktionen können nicht gelöscht oder geändert werden, öffentliche (Freund-)Funktionen jedoch schon. Es steht Ihnen frei, öffentliche (Freunde) oder nur für Sie sichtbare Funktionen zu verwenden, es sei denn, Sie möchten die aktuelle Bibliotheksfunktion für immer öffentlich machen. Sie können keine Strukturtypen löschen, keine neuen Felder hinzufügen (obwohl Sie dynamische Felder hinzufügen können) oder neue Funktionen aktualisieren. Überlegen Sie sorgfältig, wenn Sie neue Typen hinzufügen, denn einmal hinzugefügte Typen bleiben für immer bestehen!

Verwenden Sie vektorunterstützte Sammlungen (z. B. Vector, VecSet, VecMap, PriorityQueue) mit maximal 1000 Datenelementen.

Sammlungen, die dynamische Feldunterstützung verwenden (z. B. Table, Bag, ObjectBag, ObjectTable, LinkedTable), werden für alle Sammlungen verwendet, die es Dritten ermöglichen, größere Sammlungen und Sammlungen unbekannter Größe hinzuzufügen. Sui Move-Objekte haben eine maximale Größe von 250 KB – jeder Versuch, ein größeres Objekt zu erstellen, führt zum Abbruch der Transaktion. Bitte stellen Sie sicher, dass Ihr Objekt nicht größer wird als die unterstützte Sammlung des Vektors.

Wenn Ihre Funktion f eine Zahlung vom Aufrufer erfordert, beispielsweise mit SUI , verwenden Sie die Funktion fun f(zahlung: Coin) anstelle der Funktion fun f(zahlung: &mut Coin, Betrag: u64). Dies ist für den Anrufer sicherer, da er genau weiß, wie viel er zahlen muss, und sich nicht auf die Funktion f verlassen muss, um den korrekten Betrag zu extrahieren.

Es ist keine geringfügige Optimierung des Gasverbrauchs erforderlich. Bei der Berechnung der Kosten für Sui werden diese auf den nächsten Eimer gerundet, sodass nur sehr starke Schwankungen zu Gasänderungen führen. Vor allem, wenn Ihr Deal bereits in der niedrigsten Preisklasse liegt, geht es nicht günstiger. Einzelheiten entnehmen Sie bitte dem Bild unten.

Befolgen Sie die Codierungskonventionen für Move, um einen einheitlichen Stil zu erreichen.

Zusammensetzbarkeit Verwenden Sie den Anzeigestandard, um die Darstellung Ihrer Objekte in Wallets, Anwendungen und Browsern anzupassen. Vermeiden Sie die Verwendung der Funktion „Selbstübertragung“ – es ist jederzeit möglich, obj von der aktuellen Funktion zurückzugeben, anstatt transfer::transfer(obj, tx_context::sender(ctx)) zu schreiben, was dem Aufrufer oder dem programmierbaren Transaktionsblock ermöglicht (programmierbarer Transaktionsblock) verwendet obj. Test Verwenden Sie sui::test_scenario`, um ein Testszenario mit mehreren Transaktionen und mehreren Absendern zu simulieren. Verwenden Sie sui::test_utilsmodule für bessere Fehlerkorrekturmeldungen mit Assert_eq-Tests, Debug-Druck mit print und Nur-Test-Zerstörung mit destroy . Verwenden Sie sui move test --coverage, um beim Testen Informationen zur Codeabdeckung zu berechnen, und verwenden Sie sui move cover source --module, um nicht abgedeckte Zeilen anzuzeigen, die rot hervorgehoben sind. Wenn möglich, wird empfohlen, die Abdeckung auf 100 % einzustellen. Anwendungen Für optimale Leistung und Datenkonsistenz sollten Anwendungen Schreib- und Leseanforderungen auf demselben vollständigen Knoten senden. Im TS SDK bedeutet dies, dass die Anwendung die signTransactionBlock-API der Brieftasche verwenden und dann die Transaktion durch Aufrufen vonexecute_transactionBlock auf dem vollständigen Knoten der Anwendung übermitteln sollte, anstatt die signAndExecuteTransactionBlock-API der Brieftasche zu verwenden. Dies stellt die Konsistenz des Schreibens vor dem Lesen sicher – Lesevorgänge vom vollständigen Knoten der Anwendung spiegeln sofort die Schreibvorgänge der Transaktion wider, anstatt auf einen Prüfpunkt zu warten. Wenn Ihre Anwendung wissen muss, dass eine Transaktion bestätigt wurde, aber nicht sofort die Auswirkungen der Transaktion sehen oder die von der Transaktion geschriebenen Objekte/Ereignisse lesen muss, verwenden Sie zum Reduzieren der Latenz „executeTransactionBlock“ mit „showEffects“: false und „ showEvents": false . Anwendungen sollten häufig gelesene Daten lokal zwischenspeichern, anstatt sie häufig vom vollständigen Knoten abzurufen. Verwenden Sie wann immer möglich programmierbare Transaktionsblöcke, um vorhandene On-Chain-Funktionalitäten zu kombinieren, anstatt neuen Smart-Contract-Code zu veröffentlichen. Programmierbare Transaktionsblöcke ermöglichen eine groß angelegte Stapelverarbeitung und eine heterogene Zusammensetzung, wodurch die ohnehin schon niedrigen Gasgebühren weiter gesenkt werden. Anwendungen sollten das Gasbudget, den Gaspreis und die Münzauswahl dem Wallet überlassen, was dem Wallet mehr Flexibilität bietet, und es liegt in der Verantwortung des Wallets, die Transaktion zu testen, um sicherzustellen, dass die Transaktion nicht fehlschlägt. Signieren Signieren Sie niemals zwei gleichzeitige Transaktionen, die dasselbe exklusive Objekt betreffen, entweder indem Sie das exklusive Objekt separat verwenden oder indem Sie auf den Abschluss einer Transaktion warten, bevor Sie die nächste Transaktion senden. Ein Verstoß gegen diese Regel kann dazu führen, dass der Client zweideutig wird und die exklusiven Objekte, die an beiden Transaktionen beteiligt sind, bis zum Ende der aktuellen Epoche sperrt. Jeder Sui-Client-Befehl, der eine Transaktion initiiert (z. B. Sui-Client-Veröffentlichung, Sui-Client-Aufruf), kann das Flag --serialize-output akzeptieren, um eine zu signierende Base64-Transaktion auszugeben. Sui unterstützt mehrere Signaturschemata für die Transaktionssignierung, einschließlich nativer Mehrfachsignaturen.