scieee AI-readable full text Open interactive document viewer

Effiziente Implementierung von Smart Contracts für DApps auf Ethereum Virtual Machines: Eine Untersuchung zur Funktionsweise und Leistungsoptimierung

Sdrojek, Mareike

Abstract

Diese Bachelorarbeit untersucht die effiziente Implementierung von Smart Contractsfür dezentrale Anwendungen auf Ethereum Virtual Machines (EVM). Die EVM fungiertals dezentrale Ausführungsumgebung und bildet die Grundlage für Smart Contracts,wobei die Gasgebühren eine zentrale Rolle für die Effizienz solcher Anwendungenspielen. Die Arbeit zeigt spezifische Implementierungstechniken, Best Practices undEntwurfsmuster zur Gasoptimierung für Smart Contracts auf und bietet einen erstenÜberblick über Methoden zur Entwicklung kosteneffizienter DApps auf der EVM.Die Implementierungstechniken umfassen Aspekte wie Datenspeicherung, Variablen-verwaltung, Kontrollstrukturen und weiter effiziente Operationen. Es werden zweiEntwurfsmuster Smart Contracts vorgestellt und anschließend wird auf Teststrategienund -umgebungen zur Qualitätssicherung und Leistungsmessung von Smart Con-tracts eingegangen. Es erfolgt abschließend die Bewertung und Zusammenfassung derErgebnisse aus denen Best Practices abgeleitet werden.

Full text

Effiziente Implementierung von Smart Contracts für DApps auf Ethereum Virtual Machines: Eine Untersuchung zur Funktionsweise und Leistungsoptimierung Abschlussarbeit zur Erlangung des akademischen Grades: Bachelor of Science (B.Sc.) an der Hochschule für Technik und Wirtschaft (HTW) Berlin Fachbereich 4: Informatik, Kommunikation und Wirtschaft Studiengang Angewandte Informatik 1. Gutachter: Prof. Dr.-Ing. Thomas Schwotzer 2. Gutachter: Prof. Dr. Alexander Huhn Eingereicht von Mareike Sdrojek [569947] 17. November 2024 Danksagung Mit dieser Arbeit endet für mich ein oft mühsamer Bildungsweg. Nach meinem Abitur, das ich als alleinerziehende Mutter auf dem zweiten Bildungsweg absolvierte, blieb mir aufgrund der Zulassungsbeschränkungen zunächst der Zugang zum Studiengang „Angewandte Informatik“an der HTW verwehrt. Im Wintersemester 2019/2020 konnte ich endlich in den gewünschten Studiengang wechseln und hoffte, dass mein Weg nun etwas einfacher würde. Aber es kam anders - Krankheit, Verlust, Pandemie, Lockdowns, chaotisches Homeschooling. Langsam, aber irgendwie ging es dennoch weiter. Dann entschied ich mich erneut Mutter zu werden. Und nun hatte ich mit meinen drei Kindern – Teenie, Toddler und Baby – das perfekte Chaos, um eine Abschlussarbeit zu schreiben. Bedanken möchte ich mich insbesondere bei Prof. Dr.-Ing. Thomas Schwotzer und Prof. Dr. Alexander Huhn von der Hochschule für Technik und Wirtschaft in Berlin (HTW), die den Schwerpunkt „Mobile Anwendungen“mit motivierenden Themen gestalten. Durch das Modul Decentralized Systems erhielt ich die Gelegenheit, mich mit Ethereum zu befassen, was mein Interesse an diesem Thema weiter vertiefte und schließlich zur Idee für diese Abschlussarbeit führte. Ich danke zudem herzlich für die anschließende Übernahme der Betreuung und Begutachtung der Abschlussarbeit. Besonderer Dank gilt denen, die mich insbesondere in den letzten Wochen und Monaten mit den Kindern und dem Haushalt unterstützt haben. Ohne Babysitter, Haushaltshilfe, den lieben Nachbarn und den Omas, die in den letzten Tagen die großen Kids betreut haben, hätte ich bestimmt nicht nebenbei noch so eine Abschlussarbeit wie diese verfassen können. Zusammenfassung Diese Bachelorarbeit untersucht die effiziente Implementierung von Smart Contracts für dezentrale Anwendungen auf Ethereum Virtual Machines (EVM). Die EVM fungiert als dezentrale Ausführungsumgebung und bildet die Grundlage für Smart Contracts, wobei die Gasgebühren eine zentrale Rolle für die Effizienz solcher Anwendungen spielen. Die Arbeit zeigt spezifische Implementierungstechniken, Best Practices und Entwurfsmuster zur Gasoptimierung für Smart Contracts auf und bietet einen ersten Überblick über Methoden zur Entwicklung kosteneffizienter DApps auf der EVM. Die Implementierungstechniken umfassen Aspekte wie Datenspeicherung, Variablenverwaltung, Kontrollstrukturen und weiter effiziente Operationen. Es werden zwei Entwurfsmuster Smart Contracts vorgestellt und anschließend wird auf Teststrategien und -umgebungen zur Qualitätssicherung und Leistungsmessung von Smart Contracts eingegangen. Es erfolgt abschließend die Bewertung und Zusammenfassung der Ergebnisse aus denen Best Practices abgeleitet werden. Abstract This bachelor’s thesis examines the efficient implementation of smart contracts for decentralized applications on Ethereum Virtual Machines (EVM). The EVM serves as a decentralized execution environment and provides the foundation for smart contracts, where gas fees play a crucial role in the efficiency of such applications. The thesis presents specific implementation techniques, best practices, and design patterns for gas optimization in smart contracts, providing an introductory overview of methods for developing cost-effective DApps on the EVM. The implementation techniques cover aspects such as data storage, variable management, control structures and further efficient operations. Two design patterns for gas-optimized smart contracts are introduced, followed by a discussion of test strategies and environments for quality assurance and performance measurement. Finally, the thesis concludes with an evaluation and summary of results from which best practices are derived. Inhaltsverzeichnis 1. Einleitung 1 1.1. Einführung in das Thema . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2. Motivation.................................... 1 1.3. Zielsetzung und Aufgabenstellung . . . . . . . . . . . . . . . . . . . . . . 2 1.4. RelevanzdesThemas.............................. 2 1.5. AufbauderArbeit ............................... 2 2. Grundlagen 4 2.1. Web2.0undWeb3.0.............................. 4 2.2. Netzwerkarchitekturen............................. 4 2.2.1. Client-Server-Modell . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.2.2. Peer-to-Peer-Modell (P2P) . . . . . . . . . . . . . . . . . . . . . . . 5 2.3. Blockchain.................................... 5 2.3.1. Funktionsweise von Blockchains . . . . . . . . . . . . . . . . . . . 5 2.3.2. Allgemeine Merkmale von Blockchains . . . . . . . . . . . . . . . 6 2.4. Ethereum..................................... 7 2.4.1. Besonderheit von Ethereum . . . . . . . . . . . . . . . . . . . . . . 7 2.4.2. Gas: Die Währung der Rechenleistung in Ethereum . . . . . . . . 8 2.4.3. Transaktionen im Ethereum-Netzwerk . . . . . . . . . . . . . . . 12 2.4.4. SmartContracts............................. 13 2.4.5. Token................................... 14 2.5. Ethereum Virtual Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 2.5.1. Architektur und Ausführungkontext - Aufbau . . . . . . . . . . . 15 2.5.2. Funktionsweise............................. 15 2.5.3. Opcodes................................. 20 2.6. DApps - Dezentralized Applications . . . . . . . . . . . . . . . . . . . . . 25 2.7. Solidity...................................... 25 3. Anforderungen an Smart Contracts 27 3.1. Funktionale Anforderungen an die Effizienz . . . . . . . . . . . . . . . . 27 3.2. Entwurfskriterien................................ 28 3.2.1. Projekt-Setup und mögliche Toolchain für DApps . . . . . . . . . 28 4. Implementierung - Techniken für effiziente Smart Contracts 29 4.1. Einführung.................................... 29 4.1.1. Funktionsumfang der Remix IDE . . . . . . . . . . . . . . . . . . 29 4.1.2. Smart Contract Programmierung . . . . . . . . . . . . . . . . . . . 30 4.1.3. Beispiel Smart Contract RemixAI . . . . . . . . . . . . . . . . . . . 31 i Inhaltsverzeichnis 4.1.4. Token-Standards ............................ 32 4.1.5. EventsandLogs ............................ 33 4.2. Effiziente Implementierung - Gaskostenoptimierung . . . . . . . . . . . 34 4.2.1. Datenspeicherung und Datentypen . . . . . . . . . . . . . . . . . 34 4.2.2. Variablen und Speicherverwaltung . . . . . . . . . . . . . . . . . . 39 4.2.3. Optimierung Kontrollstrukturen - for-Schleifen . . . . . . . . . . 40 4.2.4. Funktionsparameter und Speicherverwaltung . . . . . . . . . . . 43 4.2.5. Effiziente Operationen und Berechnungen . . . . . . . . . . . . . 45 4.2.6. Sonstige Optimierung . . . . . . . . . . . . . . . . . . . . . . . . . 48 4.3. Best Practices und Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.3.1. Tight Variable Packing-Pattern . . . . . . . . . . . . . . . . . . . . 49 4.3.2. Memory Array Building-Pattern . . . . . . . . . . . . . . . . . . . 49 5. Teststrategien und -umgebungen für Smart Contracts 52 5.1. Testwerkzeuge.................................. 52 5.1.1. Remix - Unit Test Beispiel sol-gpt . . . . . . . . . . . . . . . . . . 55 5.2. Testnetzwerke.................................. 55 5.3. Testmethoden .................................. 56 5.3.1. Performancetests für Gasverbrauch . . . . . . . . . . . . . . . . . 56 5.3.2. CICD................................... 57 6. Bewertung der Ergebnisse 58 7. Fazit 59 7.1. Zusammenfassung ............................... 59 7.2. Beantwortung der Fragestellung . . . . . . . . . . . . . . . . . . . . . . . 60 7.2.1. BestPractices .............................. 60 7.3. Ausblick ..................................... 61 Quellenverzeichnis 62 8. Abkürzungsverzeichnis 65 9. Glossar I A. Appendix II A.1.VerändertePreise................................ II A.2.Opcodes ..................................... III ii Abbildungsverzeichnis 2.1. Etherscan Gastracker Low, Average, High 09.11.2024 . . . . . . . . . . . 10 2.2. Etherscan Heatmap 09.11.2024 . . . . . . . . . . . . . . . . . . . . . . . . 10 2.3. Etherscan Graph 09.11.2024 . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.4. Definition Gas - Auszug Yellowpaper . . . . . . . . . . . . . . . . . . . . 11 2.5. Formale Gasreferenzaus dem Yellowpaper . . . . . . . . . . . . . . . . . 13 2.6. Opcode-Matrix https://www.ethervm.io .................. 20 4.1. ScreenshotRemixIDE ............................. 29 4.2. Gaskosten von Remix am Beispiel HelloWorld.sol . . . . . . . . . . . . . 32 4.3. Logs https://www.ethervm.io/ . . . . . . . . . . . . . . . . . . . . . . . 33 4.4. StorageSlotSOLC ............................... 37 5.1. Hardhat Reporter - Übersicht Gas . . . . . . . . . . . . . . . . . . . . . . 54 5.2. Hardhat Konfiguration mit Gaskosten in EURO . . . . . . . . . . . . . . 54 A.1. Etherscan Gastracker Low, Average, High 11.11.2024 . . . . . . . . . . . II iii Tabellenverzeichnis 2.1. EinheitenvonEthereum............................ 8 2.2. Gasverbrauch nach Transaktionstyp . . . . . . . . . . . . . . . . . . . . . 9 2.3. Arithmetische Operationen - Übersicht aus Github-Repository . . . . . 21 2.4. Kontrollfluss-Operationen . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.5. Stack-, Arbeitsspeicherund Speicherverwaltung . . . . . . . . . . . . . 22 2.6. Systemoperationen ............................... 22 2.7. LogischeOperationen ............................. 23 2.8. Blockoperationen ................................ 23 2.9. Umgebungsoperationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.10. Übersicht Gaskosten [37] . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 4.1. Kostenvergleich newExam(...) und oldExam(...) ............. 35 4.2. Darstellung Variablenbelegung in Storage Slots . . . . . . . . . . . . . . 36 4.3. Dekodierte Eingaben und ihre Speicherwerte im Hexadezimalformat . 37 4.4. Kosten der verschiedenen Variablentypen und Eingaben in Gas . . . . . 37 4.5. Kostenvergleich encode(...) und decode(...) im EncoderDecoder.sol 38 4.6. Kostenvergleich Zwischenspeicherung der Array-Länge withCaching() undwithoutCaching() ............................. 42 4.7. Vergleich der Ausführungskosten der Funktionen vanilla_loop() und loop_unchecked_plusplus() ......................... 42 4.8. Kostenvergleich loop_unchecked_plusplus() und loop_unchecked() . 43 4.9. Kostenvergleich CMemory.add(...) und CCalldata.add(...) mit den jeweiligen Gas-Differenzen. . . . . . . . . . . . . . . . . . . . . . . . . . . 45 4.10. Kostenvergleich von den Funktionen checkStrict() und checkNonStrict() .......................................... 45 4.11. Kostenvergleich Require.check1() und Require.check2() ....... 46 4.12. Kostenvergleich modifierund internal view-Funktion . . . . . . . . 47 iv Listings 4.1. HelloWorld.sol ................................. 31 4.2. BitCompaction.sol................................ 34 4.3. BitCompaction.sol................................ 35 4.4. CompressingExample.sol . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 4.5. EncoderDecoder.sol............................... 38 4.6. For-Loopi .................................... 40 4.7. For-Looparray ................................. 41 4.8. GasSavings.sol.................................. 41 4.9. vanilla_loop() .................................. 42 4.10.loop_lte()..................................... 42 4.11. loop_unchecked_plusplus() . . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.12.loop_unchecked()................................ 43 4.13.CMemory.sol................................... 44 4.14.Calldata.sol ................................... 44 4.15.CheckStrict.sol.................................. 45 4.16.Requires.sol ................................... 46 4.17.Inlined.sol .................................... 47 4.18.Modifier.sol ................................... 47 4.19.Batching ..................................... 48 4.20. Store.sol (MemoryArrayBuilding) . . . . . . . . . . . . . . . . . . . . . . 50 5.1. testGascosts.js.................................. 53 5.2. GasLimit.sol................................... 55 5.3. TestGasLimit.sol................................. 55 v 1. Einleitung 1.1. Einführung in das Thema Das Ziel dieser Arbeit ist es, für die Entwicklung von dezentralen Anwendungen einen Überblick zu verschaffen, wie man Smart Contracts für DApps wirtschaftlich durch geringe Gaskosten entwickelt. Bei jeder Ausführung einer Transaktion auf der Ethereum-Blockchain und somit auch bei der Ausführung eines Smart Contract entstehen Gaskosten. Gaskosten werden für verschiedene Rechenoperationen in der Ethereum Virtual Machine, kurz EVM, relevant. Die Art und Weise, wie die Smart Contracts geschrieben werden, beeinflusst die Gesamtkosten. Als Programmiersprache wird in dieser Arbeit Solidity, eine der am weit verbreitesten Sprache für die Entwicklung von Smart Contracts, verwendet. Viele Bereiche sind zukünfig von besonderem Interesse. Für die Entwicklung von blockchainbasierten Anwendungen ist solides Wissen über die Funktionsweise der EVM notwendig, damit gute und effiziente Smart Contracts auf einer Blockchain entwickelt werden können. Die Nutzung der Blockchain-Technologie ermöglicht langfristig einen Wegfall von Intermediären in Bereichen, in denen eine Institution wie eine Bank oder Notare notwendig sind. Das Spektrum an Anwendungsgebieten für DApps ist vielfältig und umfasst: • Online-Rechtsverträge, z.B. für Versicherungen • die Ausgabe von Wertpapieren, z.B. Anleihen • dezentrale Wallets und Anwendungen • Tokenisierung, z.B. von Immobilien • DeFi (dezentrale Finanz) • dezentrale Videospiele • die dezentrale Cloud, die ursprüngliche Berufung von Ethereum • fungible und anpassbare Token mit dem ERC20-Token • NFTs mit dem ERC721-Token [9] 1.2. Motivation Die Eigenschaften, dass eine Blockchain öffentlich, transparent, sowie ohne zentrale Instanz funktioniert und irreversibel ist, ermöglichen viele neue Anwendungsgebiete. Beispielsweise können Zahlungsprozesse, die derzeit ressourcenintensiv sind und aufgrund vieler Intermediäre nicht kontinuierlich stattfinden, durch BlockchainTechnologie effizienter und schneller abgewickelt werden. Im Kapitalmarkthandel 1 2. Grundlagen dieser Smart Contracts dezentrale Anwendungen, sogenannte DApps (decentralized Applications), funktionieren. Smart Contracts sind selbstausführende „Verträge“, deren Bedingungen direkt im Code festgelegt sind. Der ERC-20 Smart Contracts Standard ist ein Beispiel dafür, wie ein Smart Contract in Ethereum funktioniert. [5] [3] 2.4.2. Gas: Die Währung der Rechenleistung in Ethereum „Ether is the main internal crypto-fuel of ethereum“[10] Die Rolle von Ether (ETH) Die Währungseinheit von Ethereum wird Ether genannt und mit ETH abgekürzt. Die kleinstmögliche Einheit ist Wei 5 . Ether ermöglicht es Miner zu bezahlen, um mit der EVM Transaktionen durchführen oder mit Smart Contracts interagieren zukönnen. Die Gebühren werden Gas genannt und in der Einheit Gwei 6 ausgedrückt, wobei 1 Gwei = 10−9ETH. sind.[9] Eine Bezeichnung der Einteilung in Zwischeninheiten zeigt folgende Tabelle [10] Einheit Name 1wei 1012 szabo 1015 finney 1018 ether Tabelle 2.1.: Einheiten von Ethereum Gaspreise und ihre Dynamik Gaspreise sind nicht statisch und schwanken alle 14 Sekunden je nach Netzwerküberlastung. Zu den Hauptfaktoren, die Gaspreise beeinflussen, gehören die Nachfrage nach Blockspace und die aktuellen Gaspreise. Wenn mehr Benutzer Transaktionen durchführen möchten, steigt der Preis für Gas, da Miner für die Bearbeitung ihrer Transaktionen priorisiert werden. Aktuelle Gaspreise können auf Plattformen wie Etherscan7 verfolgt werden. Die Gesamtkosten setzen sich aus mehreren Komponenten zusammen. •Basiskosten Wird vom Netzwerk festgelegt und muss für eine Transaktion gezahlt werden, 5benannt nach dem Kryptographen Wei Dai 6„Giga" 7https://etherscan.io/gastracker#chart_gasprice 8 2. Grundlagen z.B. 21 000 Gas für eine Transaktionsausführung , 32 000 Gas Erstellung eines Accounts erstellen •Prioritätskosten optionales ”Trinkgeld“, soll Nodes motivieren die Transaktion aufzunehmen •Gaseinheiten siehe Tabelle 2.2: Komplexere Aktionen verbrauchen mehr Gas als einfache Die Formel zur Berechnung der Gaskosten lautet: Gasgebühr =Verbrauchte Gaseinheiten ×(Basiskosten +Prioritätskosten) Die meisten Wallets berechnen den Gasverbrauch der Smart Contracts und zeigen ihn auf eine einfache Weise an. Es gibt einige fixe Kosten, die immer anfallen und zusätzliche Kosten je nach Programmierung der Smart Contracts sowie sonstigen Anwendungsfällen. Transaktionstyp Gaseinheiten Senden von ETH 21 000 Senden von ERC-20-Token 65 000 Übertragung von NFT 84 904 Tauschen auf Uniswap 184 523 Tabelle 2.2.: Gasverbrauch nach Transaktionstyp Diese Tabelle zeigt die variierenden Gasverbrauchswerte, die Benutzer beim Senden oder Interagieren mit verschiedenen Token berücksichtigen müssen. Es ist wichtig, dass Benutzer die Gasgebühren vor der Durchführung einer Transaktion genau abschätzen, um unerwartete Kosten zu vermeiden.[33] 9 2. Grundlagen Transaktionkosten mit Gaspreis - Ein Berechnungsbeispiel Abbildung 2.1.: Etherscan Gastracker Low, Average, High 09.11.2024 Abbildung 2.2.: Etherscan Heatmap 09.11.2024 Abbildung 2.3.: Etherscan Graph 09.11.2024 Beispielberechnung der Transaktionskosten Gegeben: •Gaslimit: 21 000 Gas •Gaspreis: 11,556 Gwei (AVGPreis aus 2.1) •ETH-Preis in USD: $3,077.32 •Umrechnungskurs: 1 USD = 0.9329 EUR Transaktionskosten (Gwei) = 21 000 ×11.556 =242.676 Gwei Transaktionskosten (ETH) =242.676 109=0,000242676ETH Transaktionskosten (USD) =0,000242676 ×3077.32 =0, 7468USD Transaktionskosten (EUR) =0,7468 ×0, 9329 =0, 6967 EUR Ergebnis: Die Transaktionskosten betragen ca. 0.75 USD oder 0.70 EUR . Stand: 9.11.2024 22:25 Uhr 10 2. Grundlagen Die Bedeutung von Gas Abbildung 2.4.: Definition Gas - Auszug Yellowpaper Gas ist mehr als ein Maß für Transaktionskosten. Gas und die damit verbundenen Gebühren sichern die Integrität des Ethereum-Netzwerks, d.h. es ist auch ein Sicherheitsmechanismus für das Netzwerk. Durch die Anforderung von Gebühren für die Verarbeitung von Transaktionen wird das Risiko von überlastenden, betrügerischen Aktivitäten minimiert. Ein Angreifer müsste erhebliche Ressourcen aufwenden, um das Netzwerk zu überlasten, was aufgrund der Kosten für Gas unwirtschaftlich ist. Dies schützt das Netzwerk vor ressourcenintensiven Berechnungen und potenziellen Denial-of-Service-Angriffen. Bevor eine Transaktion einer Blockchain hinzugefügt wird, wird diese validiert. Miner enthalten für das Validieren und Hinzufügen eine Entschädigung. Diese Validierungsgebühren (in Gas) variieren und hängen von verschiedenen Faktoren ab, wie z.B. den Forks 8 und Variablen. Der aktuelle Gaspreis variiert je nach Nachfrage nach Blockspace und wird in ETH pro Gas gemessen. Je höher die Nachfrage, desto höher der Gaspreis. Die Größe von calldata spielt eine wichtige Rolle für den Gaspreis. Jedes Byte in calldata kostet Gas: Ein Byte mit dem Wert 0 kostet 4 Gas, während andere Bytes 16 Gas kosten (vor der Hardfork Istanbul betrug der Preis 64 Gas pro Byte). Jede Transaktion hat intrinsische Kosten von 21 000 Gas. Bei der Erstellung eines Contracts kommen weitere 32 000 Gas hinzu. Diese Kosten müssen vor der Ausführung eines Opcodes oder Transfers bezahlt werden. Es gibt statische und dynamische Ausführungskosten. Die statischen Ausführungskosten sind für jeden Opcode gleich. Diese Kosten werden zum Zeitpunkt der Ausführung berechnet und sind für alle Ausführungsarten gleich. Sie können sich jedoch durch zukünftige Hardforks ändern. Einige Anweisungen erfordern abhängig von ihren Parametern mehr Arbeit und verursachen daher dynamische Kosten. Diese Kosten hängen von verschiedenen Faktoren ab und können sich auch mit neuen Hardforks ändern. Die dynamischen Ausführungskosten sind detailliert in der Ethereum-Dokumentation auf ethereum.org 9 sowie auf evm.codes 10 beschrieben.[20] Eine vollständige Übersicht der Kosten der Opcodes befindet sich im Anhang in Tabelle A.1. Zu den Operationen, die kein Gas kosten, gehören das Lesen von Zustandsvariablen, wie das Abfragen des Kontostands 8 „Forks entstehen, wenn größere technische Aktualisierungen oder Änderungen am Netzwerk vorgenommen werden müssen – sie gehen in der Regel aus Ethereum-Verbesserungsvorschlägen (EIPs) hervor und ändern die „Regeln“ des Protokolls. https://ethereum.org/de/history/ “ 9ethereum.org 10evm.codes 11 2. Grundlagen über <address>.balance oder this.balance, sowie das Lesen von Blockvariablen wie tx oder sg. Ebenso kosten das Aufrufen von reinen Funktionen und das Lesen von Opcodes in der Inline-Assembly kein Gas. Operationen, die Gas kosten sind das Senden von Ether, das Erstellen von Contracts und das Ändern von Zustandsvariablen. Außerdem wird Gas verbraucht, wenn ein Event gesendet wird, eine nicht-reine Funktion aufgerufen wird oder ein Contract durch Selfdestruct zerstört wird. Low-Level-Aufrufe sowie das Schreiben von Opcodes in der Inline-Assembly sind ebenfalls mit Gaskosten verbunden.[37] Das Verständnis der Datenrepräsentation von Solidity 11 in der EVM, die Art und Weise, wie die EVM Daten und ihre Assembler-Implementierung speichert, ist entscheidend, um den Funktionsmechanismus von Solidity zu verstehen und die Gaskosten genau abschätzen zu können. Beispielsweise kostet der Opcode SSTORE etwa 20.000 Gas, was etwa dem 5.000-fachen eines einfachen arithmetischen Opcodes(3 bis 5 Gas) entspricht. Im Gegensatz dazu kostet der Opcode SLOAD etwa 200 Gas, also das 100-fache einer einfachen arithmetischen Operation. [37] 2.4.3. Transaktionen im Ethereum-Netzwerk Eine Transaktion ist eine autorisierte Anfrage zur Änderung von Daten auf einer Blockchain. Diese Anfrage kann verschiedene Formen annehmen, wie z. B. die Überweisung von Kryptowährungen, die Ausführung eines Smart Contracts oder die Aktualisierung von Informationen in einem dezentralisierten Ledger. [21] Transaktionen sind signierte Nachrichten, die von externen Konten (EOAs) stammen und in der Blockchain gespeichert werden. Sie lösen Zustandsänderungen in der EVM aus und können Smart Contracts ausführen. Eine spezielle RLP-Codierung (Recursive Length Prefix) wird verwendet, um Transaktionen effizient zu serialisieren. Jede Transaktion enthält eine Vielzahl von Feldern wie Nonce, Gaspreis, Gaslimit, Empfängeradresse, Wert und optionale Daten, die jeweils eine bestimmte Funktion erfüllen. Jede Transaktion muss eine bestimmte Menge an Gas bereitstellen, die für ihre Ausführung verwendet wird, um den Hauptmechanismus sicherzustellen. Wenn das Gas während der Ausführung aufgebraucht wird, wird die Transaktion gestoppt und alle Änderungen rückgängig gemacht. Die bereits verbrauchten Gasgebühren sind verloren, was den Sender dazu zwingt, das Gaslimit realistisch zu setzen. Die Nonce zählt die Anzahl der bestätigten Transaktionen von einem Konto und verhindert doppelte Transaktionen. Der Gaspreis wird vom Sender in Wei festgelegt und bestimmt, wie viel er pro Gaseinheit zu zahlen bereit ist. Das Gaslimit legt die maximale Gasmenge fest, die für die Transaktion verwendet werden kann. Sobald eine Transaktion vom Sender signiert ist, wird sie über das Peer-to-PeerNetzwerk von Ethereum verbreitet. Mithilfe eines Flood-Routing-Protokolls erreicht die Transaktion innerhalb von Sekunden Nodes weltweit, die Kopien der Transaktion speichern und weiterleiten. [3] 11Programmiersprache für Smart Contracts 12 2. Grundlagen Abbildung 2.5.: Formale Gasreferenzaus dem Yellowpaper 2.4.4. Smart Contracts Der Kryptologe Nick Szabo prägte den Begriff Smart Contracts bereits in den 1990ern. Das Konzept der Smart Contracts hat sich insbesondere durch Ethereum weiterentwickelt. Sie sind die grundlegenden Bausteine der Anwendungsebene von Ethereum. [17] Smart Contracts sind geschlossene, unveränderliche Programme auf der Blockchain, die spezifischen Aktionen auf der EVM ausführen können. [3] Sie bieten zahlreiche Einsatzmöglichkeiten, die durch Programmierfähigkeiten, Vorstellungen und gegebenenfalls rechtliche Rahmenbedingungen begrenzt sind. Für die Einbindung externer Informationen sind Orakel erforderlich [9]. Ein Smart Contract ist ein computergestütztes Transaktionsprotokoll, das die im „Vertrag“ festgelegten Bedingungen automatisch ausführt. Die Hauptziele dabei sind die Sicherstellung, dass allgemeine Vertragsbestimmungen – wie Zahlungsmodalitäten, Pfandrechte, Vertraulichkeit und Durchsetzung – erfüllt werden, das Risiko böswilliger oder zufälliger Abweichungen zu minimieren und den Bedarf an vertrauenswürdigen Vermittlern zu reduzieren. [27] „Das Potential für die Nutzung intelligenter Verträge ist nahezu unbegrenzt“[9] Die Ausführung von Smart Contracts auf Ethereum ist 13 2. Grundlagen deterministisch und an den Zustand der Blockchain sowie den Kontext der auslösenden Transaktion gebunden [3]. Jeder kann eigene Smart Contracts entwickeln, um spezifische Funktionen zu realisieren [15]. Lebenszyklus eines Smart Contracts Smart Contracts werden in Hochsprachen wie z.B. Solidity geschrieben und anschließend in Low-Level-Bytecode übersetzt. Eine Ausführung eines Smart Contracts ist nur möglich, wenn er von einer Transaktion aufgerufen wurde. Sie laufen niemals von alleine und können auch nicht parallel ausgeführt werden. Smart Contracts arbeiten in einer hochgradig beschränkten und minimalistischen Ausführungsumgebung, der EVM. Um Kosten durch Programmierfehler zu vermeiden, ist es von besonderem Interesse und sehr wichtig, Smart Contracts ohne negative Nebeneffekte zu entwickeln. [3] 2.4.5. Token Token können durch die Verwendung von Smart Contracts erzeugt werden und werden. Sie werden ebenfalls auf einer Blockchain ausgeführt. Sie stellen digitale Geldeinheiten dar, die keine eigene Blockchain besitzen, sondern eine andere nutzen, typischerweise die Ethereum-Blockchain. Auf Ethereum können innovative digitale Token entwickelt werden, die besondere Eigenschaften aufweisen. [9] Token stellen einen Vermögenswert oder einen Nutzen dar und können gehandelt oder getauscht werden. Im Gegensatz zu Altcoins 12 nutzen Token in der Regel eine bereits bestehende Blockchain. Das Herausbringen eines Tokens benötigt keine Änderung des zugrunde liegenden Protokolls und ist leichter herauszubringen als Altcoins. Um einen neuen Token zu erstellen kann man auf einer Standardvorlage basierenden Ansatz verfolgen. Dieser Prozess dauert nur wenige Stunden. [21] Ein Beispiel für Token und eine ABI-Spezifikation sind die ERC-20 Token, die fungible digitalen Token. ERC-20-Token haben die gleiche ABI 13 , wodurch ein handeln an denselben Börsen aufgrund der gemeinsamen Schnittstelle möglich ist. Die zugrunde liegende Spezifikation eines einzelnen Tokens kann jedoch völlig unterschiedlich sein und ist im jeweiligen Bytecode definiert ist. [21] 12Kryptwährungen, die nicht Bitcoin sind 13Application Binary Interface 14 2. Grundlagen 2.5. Ethereum Virtual Machine Die Ethereum Virtual Machine ist eine globale Instanz eines Computers. Sie wird als gemeinsamer Zustand im gesamten Ethereum-Netzwerk betrieben, wobei jeder Knoten eine lokale Kopie der EVM hält, um Smart Contracts zu validieren [3]. Da die EVM der kanonische 14 Computer des Netzwerks ist, einigen sich alle Teilnehmer auf ihren Zustand. Die EVM übernimmt das Deployment und die Ausführung von Smart Contracts. Für einfache Werttransfers zwischen zwei EOAs ist sie nicht erforderlich, bei allen anderen Interaktionen jedoch ist eine durch die EVM berechnete Zustandsaktualisierung erforderlich. Die EVM aktualisiert den Zustand gemäß den Vorgaben des EthereumProtokolls, indem sie die gültigen Zustandsübergänge durch die Ausführung von Smart Contracts berechnet [3]. Sie verwendet eine Reihe von Opcode-Anweisungen, um bestimmte Aufgaben auszuführen. 140 einmaligen Opcodes machen es möglich, dass die EVM turingvollständig ist.[15] Der Code wird in Bytecode kompiliert und kann dann auf der von Minern bereitgestellten nicht-virtuellen Computerhardware laufen. [21] Als dezentrale Cloud fungiert die EVM für die Entwicklung, Speicherung und das Hosting aller Arten von dezentralen Anwendungen in der Blockchain. [9] 2.5.1. Architektur und Ausführungkontext - Aufbau Die EVM-Architektur ist stackbasiert. Alle Speicherwerte haben eine Wortgröße von 256 Bit und werden in einem Stack abgelegt. Der Grund für die Wortgröße ist, dass native Hashoperationen und Operationen mit elliptischen Kurven unterstützt werden können.[21] Die EVM verfügt über unterschiedliche Speicher: •Calldata read-only für Programmcode, der mit dem Bytecode des auszuführenden Smart Contracts geladen wird. •Memory flüchtiger Arbeitsspeicher, bei dem jede Speicherstelle explizit mit null initialisiert wird. Unendlich erweiterbares Array. Analogie: RAM •Storage read-write, persistent, Teil des Ethereum-Zustands und ist Null initialisiert. Zusätzlich gibt es eine Reihe von Umgebungsvariablen und Daten, die während der Ausführung zur Verfügung stehen. [3] 2.5.2. Funktionsweise So wie andere virtuelle Maschinen auch, wird durch die VM ein Abstraktionsgrad zwischen dem ausführenden Code und der ausführenden Maschine erzeugt. Die EVM ist auf vielen Nodes auf der ganzen Welt verteilt.[15] Als Rechenwerk bietet die EVM eine Abstaktion für Berechnungen und Speicher, ähnlich einer JVM (Java Virtual Machine). Die EVM nutzt einen eigenen Bytecode-Befehlssatz, 14 Kanonisch (lateinisch canonicus „regelgerecht“; vom griechischen kanonikós), bedeutet „den Regeln entsprechend“. Weitere Informationen unter https://de.wikipedia.org/wiki/Kanonisch. 15 2. Grundlagen der aus Smart-Contract-Programmiersprachen erzeugt wird. Die Ausführungsreihenfolge der EVM wird extern organisiert, da sie kein internes Scheduling besitzt. Clients durchlaufen verifizierte Blocktransaktionen, um die Reihenfolge zu bestimmen, in der Smart Contracts ausgeführt werden. Dies bedeutet, dass die EVM als Single-ThreadMaschine fungiert. Ohne direkte Systemschnittstelle und ohne Hardwaresupport ist sie eine vollständig virtuelle Maschine und keine physische Einheit mit einer direkten Schnittstelle [3]. In der EVM beziehen alle Befehle ihre Parameter vom Stack, mit Ausnahme des Befehls PUSHx , der seine Parameter direkt aus dem Code liest. Jede Anweisung erwartet bestimmte Eingaben auf dem Stack und liefert Rückgabewerte, die ebenfalls auf den Stack gelegt werden [20]. Codeausführung Der Code besteht aus mehreren Bytes, wobei jedes Byte eine bestimmte Operation repräsentiert. Allgemein ist die Codeausführung eine Endlosschleife, die darin besteht, die Operation am aktuellen Programmzähler (PC), der bei Null beginnt, auszuführen und anschließend zu inkrementieren, bis das Codeende erreicht ist, ein STOP - oder RETURN-Befehl gelesen wird oder ein Fehler auftritt. Diese Operationen haben Schreibzugriff auf die o.g. unterschiedlichen Arten von Speichern. Der Code hat Zugriff auf den Wert, den Sender und Daten der Eingangsnachrichten, als auch auf die Daten des Block Headers. Ebenfalls kann der Code ein Byte-Array von Daten als Ausgabe zurückgeben. Das formale Ausführungsmodell von EVM-Code ist einfach: Während die virtuelle Maschine von Ethereum läuft, kann ihr vollständiger Berechnungszustand durch das Tupel (block_state, transaction, message, code, memory, stack, pc, gas) beschrieben werden, wobei block_state der globale Zustand, der alle Account-Informationen sowie die Salden als auch die Speicherung enthält. Ausführungsumgebung Bei der Ausführung eines Smart Contracts erstellt die EVM einen Kontext. Dieser umfasst mehrere Datenbereiche, die jeweils einen spezifischen Zweck erfüllen. Zusätzlich beinhaltet der Kontext Variablen wie den Programmzähler (PC), den aktuellen Aufrufer (Caller), den aufgerufenen Vertrag (Callee) und die aktuelle Adresse des ausgeführten Codes. Code Hier werden Anweisungen gespeichert. Die persistenten Daten sind Teil des "Contact Account State Field". Die Code-Bereiche von Externally owned accounts (EOAs) sind leer. Code sind die Bytes, die von der EVM während der Ausführung des 16 2. Grundlagen Smart Contracts gelesen, interpretiert und ausgeführt werden. Der Code ist unveränderlich aber er kann mit den Anweisungen CODESIZE und CODECOPY gelesen werden. Die Anweisungen EXTCODESIZE und EXTCODECOPY ermöglichen es, dass der Code eines Contracts von den anderen Contracts gelesen werden kann. Der Program Counter (PC) liest die Instruktionen, die im Code gespeichert sind und als nächstes gelesen werden sollen. In der Regel wird er um ein Byte inkrementiert, um auf die nächste Anweisung zu verweisen. Ausnahmen hiervon sind: •PUSHx : Diese Anweisung ist länger als ein einzelnes Byte und veranlasst den Program Counter seinen Parameter zu überspringen. •JUMP : Diese Anweisung erhöht nicht den Wert des Program Counters, sondern ändert den Programmzähler an eine Position, die durch den oberen Rand des Stacks festgelegt ist. •JUMPI : Diese Anweisung verhält sich ähnlich wie JUMP , jedoch nur, wenn die Bedingung erfüllt ist (ein Code-Wert ungleich Null). Andernfalls wird der Program Counter wie bei anderen Befehlen inkrementiert. Jede Ausführungsrunde wird durch das Setzen des Program Counters PCauf die n-te Position im Befehlssatz der EVM gesteuert. Jede Instruktion hat ihre eigene Definition im Bezug auf die Ausführung für das o.g. Tupel. Befehl Beschreibung ADD Liest POP zwei Elemente vom Stack und fügt die Summe der beiden Elemente zum Stack hinzu PUSH. Reduziert das Gas um 1 und inkrementiert den Programmzähler PC um 1. SSTORE Nimmt die oberen beiden Elemente vom Stack POP und fügt das zweite Element an dem vom ersten angegebenen Index in den Contract Storage hinzu. Reduziert das Gas um 200 und inkrementiert den Programmzähler PC um 1. [10] Der Stack ist eine Liste von 32-Byte-Elementen und wird zum Speichern der Einund Augaben von Smart-Contract-Anweisungen verwendet. Für jeden Aufrufkontext wird ein Stack erstellt, der bei Beendigung des Aufrufkontexts zerstört wird. Der Stack hat derzeit eine Höchstgrenze von 1024 Werten. Alle Anweisungen interagieren mit dem Stack. Änderungen können mit den Stack-Anweisungen wie PUSH1 , POP , DUP1 , or SWAP1 erfolgen. [20] Memory Memory ist nicht persistent und wird nach dem Aufrufkontext zerstört (ephemeral). Zu Beginn wird der memory -Speicher der EVM auf 0 initialisiert. Lesen und 17 2. Grundlagen Umgebungsoperationen Opcodes für den Umgang mit Informationen der Ausführungsumgebung: [18] Befehl Beschreibung (der Rückgabe) GAS Menge des verfügbarem Gas (nach Abzug dieser Anweisung). ADDRESS Adresse des ausführenden Account. BALANCE Guthaben eines beliebigen Accounts. ORIGIN Adresse des EOAs,das diese EVM-Ausführung initiiert hat. CALLER Adresse des Aufrufers, der unmittelbar für diese Ausführung verantwortlich ist. CALLVALUE Ether-Betrag, der vom CALLER eingezahlt wurde. CALLDATALOAD Eingabedaten, die vom CALLER gesendet CALLDATASIZE Größe der Eingabedaten zurück. CALLDATACOPY Kopiert die Eingabedaten in den Speicher. CODESIZE Codegröße, des aktuell in der Umgebung ausgeführten Codes. CODECOPY Kopiert aktuellen in Umgebung ausgeführt Code in den Speicher. GASPRICE Gaspreis, der von der ursprünglichen Transaktion angegeben wurde. EXTCODESIZE Codegröße eines beliebigen Accounzs zurück. EXTCODECOPY Kopiert den Code eines beliebigen Accounts in den Speicher. RETURNDATASIZE Gibt die Größe der Ausgabedaten aus dem vorherigen Aufruf in der aktuellen Umgebung zurück. RETURNDATACOPY Kopiert die Ausgabedaten aus dem vorherigen Aufruf in den Speicher. Tabelle 2.9.: Umgebungsoperationen Überichten aus dem Github-Repository [18] 24 2. Grundlagen Häufig verwendete Opcodes und ihre entsprechende Gaskosten Operation Gas Art der Operation ADD/SUB 3 Arithmetik MUL/DIV 5 Arithmetik ADDMOD/MULMOD 8 Arithmetik AND/OR/XOR 3 Logik LT/GT/SLT/SGT/EQ 3 Logik POP 2 Stack PUSH/DUP/SWAP 3 Stack MLOAD/MSTORE 3 Speicher JUMP 8 Kontrollfluss JUMPI 10 Kontrollfluss SLOAD 200 Speicher SSTORE 5000/20000 Speicher BALANCE 400 Umgebung CREATE 32000 System CALL 25000 System Tabelle 2.10.: Übersicht Gaskosten [37] 2.6. DApps - Dezentralized Applications Die Entwicklung dezentraler Anwendungen erfordert eine Kombination aus FrontendTechnologien und Smart-Contract-Programmierung. Für die Gestaltung benutzerfreundlicher Oberflächen bieten sich Frontend-Frameworks wie Vue, Angular oder React an. Diese Frameworks ermöglichen es Entwicklern, interaktive und responsive Benutzeroberflächen zu erstellen, die mit der Blockchain-Infrastruktur kommunizieren können. Während für das Frontend verschiedene Optionen zur Verfügung stehen, konzentriert sich diese Arbeit bei der Programmierung von Smart Contracts ausschließlich auf die Hochsprache Solidity. Im Folgenden werden spezifische Konzepte und Aspekte von Solidity hervorgehoben, die besonders relevant für die Optimierung von Gasgebühren sind. Diese Optimierungen sind von entscheidender Bedeutung, da sie direkt die Effizienz und Kosteneffektivität der Smart Contracts beeinflussen. Durch die gezielte Betrachtung dieser Aspekte soll ein grundlegendes Verständnis für die Entwicklung gaseffizienter Smart Contracts erarbeitet werden, was in der ressourcenbeschränkten Umgebung der Ethereum Virtual Machine nützlich ist. 2.7. Solidity Solidity ist eine Programmiersprache für Ethereum Smart Contracts und wurde von Dr. Gavin Wood 17 entwickelt. Sie ist speziell für die EVM konzipiert und zeichnet 17Co-Founder Ethereum und Founder Polkadot(Parachain) und Verfasser des Ethereum Yellowpapers 25 2. Grundlagen sich durch ihre statische Typisierung aus. Das Hauptprodukt des Solidity-Projekts ist der Compiler solc , der Solidity-Code in EVM-Bytecode übersetzt. Zudem verwaltet das Projekt den wichtigen ABI-Standard für Smart Contracts.[3] Die Sprache vereint Einflüsse verschiedener Programmiersprachen. Von C++ übernimmt Solidity Elemente wie die Syntax für Variablendeklarationen, for-Schleifen, Funktionsüberladung und Typkonvertierungen. Der Einfluss von JavaScript wurde zwar seit Version 0.4.0 reduziert, bleibt aber in der Funktionsdefinition mit dem Schlüsselwort function erkennbar. Python hat ebenfalls Spuren in Solidity hinterlassen, insbesondere in Form von Modifikatoren (ähnlich den Python-Dekoratoren), Mehrfachvererbung, C3-Linearisierung und dem Super-Schlüsselwort. Auch die Zuweisungsund Kopiersemantik von Wertund Referenztypen wurde von Python übernommen. Solidity unterstützt Konzepte wie Vererbung, Bibliotheken und komplexe benutzerdefinierte Typen. Diese Kombination von Eigenschaften macht Solidity zu einer leistungsfähigen und flexiblen Sprache für die Entwicklung von Smart Contracts auf der Ethereum-Plattform. Durch die Integration von Elementen aus verschiedenen Programmiersprachen bietet Solidity Entwicklern eine auf die spezifischen Anforderungen von Blockchain-Anwendungen zugeschnittene Umgebung. [31] 26 3. Anforderungen an Smart Contracts Aufgrund der Komplexität des Themas erfolgt keine praktische Implementierung in Form einer DApp. Der Fokus liegt deswegen auf den relevanten Aspekten, die für kosteneffiziente und leistungsfähige dezentrale Anwendungen entscheidend sind. Eine Überlegung hinsichtlich der Effizienz ist die klare Definition dessen, was der Smart Contract tatsächlich leisten soll. Dazu gehört die Analyse der spezifischen Aufgaben, die der Smart Contract ausführen soll, sowie die Identifikation der verschiedenen Anwendungsfälle, die er unterstützen muss. Effiziente Smart Contracts sind so optimiert, dass die für die Ausführung notwendigen Ressourcen und Kosten auf ein Minimum beschränkt sind. Eine zentrale Rolle bei der Entwicklung von Smart Contracts spielt immer die Gaseffizienz, da jede Operation Gas verbraucht und somit die Transaktionskosten beeinflusst. In diesem Zusammenhang stellt sich die zentrale Frage, wie Gaskosten effektiv minimiert werden können. Wichtig ist, gasintensive Operationen zu identifizieren und die Optimierungsmöglichkeiten zu kennen. Nur so ist es möglich, die Effizienz der Smart Contracts zu steigern. Wie die Effizienz von Smart Contracts zu verbessern und die Gaskosten zu minimieren sind, wird in den folgenden Abschnitten vorgestellt. 3.1. Funktionale Anforderungen an die Effizienz Folgene Methoden und Anforderungen bilden die Grundlage für einen Smart Contract, der sowohl leistungsfähig als auch kosteneffizient ist. •Minimierung der Storage-Speicherzugriffe Speicheroperationen, die mit hohen Gaskosten verbunden sind, meiden, denn jeder Speicherzugriff verursacht Kosten, die die Gesamteffizienz beeinträchtigen. •Reduzierung der Code-Komplexität Einfache, direkte Implementierungen bevorzugen, um Ausführungsgeschwindigkeit zu steigern und Gaskosten zu senken. Vermeidung überflüssiger Berechnungen und Redundanzen. •Effizienter Umgang mit externen Speicherressourcen Ein sparsamer Umgang mit Speicherressourcen, da Speicher auf der Blockchain teurer ist als auf anderen Datenbanken. •Datentypwahl und sorgfältige Variablenverwaltung •Anzahl der Transaktionen minimieren Transaktionen so gering wie möglich halten, da diese mit 21 000 Gas erheblichen Einfluss auf die Gesamteffizienz haben. •Off-Chain-Berechnungen Komplexe Berechnungen außerhalb der Blockchain durchführen und Ergebnisse 27 3. Anforderungen an Smart Contracts in einer einzigen Transaktion übermitteln, um Rechenressourcen und Kosten zu reduzieren. 3.2. Entwurfskriterien Allgemeine Prinzipien der Softwareentwicklung und „Best Practices“sind bereits beim Entwurf zu berücksichtigen. Ein zentraler Aspekt bei der Entwicklung ist auch bei DApps das Code-Design und die Architektur. Komplexe Funktionen sollten in kleinere, wiederverwendbare Komponenten zerlegt werden. Dies fördert die Modularität und erleichtert sowohl die Wartung als auch das Verständnis des Codes. Es sollte möglich sein, einen Smart Contract zu aktualisieren, ohne die bestehende Funktionalität zu beeinträchtigen. Zur Überprüfung der Sicherheitsmechanismen sollten Code-Analysen und Tests durchgeführt werden, um mögliche Schwachstellen frühzeitig zu erkennen. Zusätzlich zur Gaskostenoptimierung im Hinblick auf die Effizienz sind auch Speicheroptimierungen wichtig, da das Speichern auf der Blockchain teurer ist als auf Alternativen. Beim Testen sollten verschiedene Ansätze verfolgt werden, wie z.B. Unit-Tests, um einzelne Komponenten eines Smart Contracts isoliert zu testen, sowie Integrationstests, um zu überprüfen, wie die verschiedenen Komponenten zusammenarbeiten. Abschließend sollte man eine Simulation in Betracht ziehen und ggf. ein Testnetzwerk wie Ganache und Simulatoren nutzen, um reale Bedingungen nachzubilden. 3.2.1. Projekt-Setup und mögliche Toolchain für DApps Für die Entwicklung und das Testen von Smart Contracts stehen verschiedene Tools und Frameworks zur Verfügung. Die Einrichtung einer lokalen Ethereum-Blockchain, beispielsweise mit Geth (Go-Ethereum), ermöglicht das Testen und Debuggen von Smart Contracts in einer kontrollierten Umgebung. Ganache bietet zudem ein leicht einzurichtendes lokales Testnetzwerk und ermöglicht schnelle Tests ohne eine öffentliche Blockchain. Weitere wichtige Tools sind Truffle, ein umfangreiches Entwicklungsframework für Ethereum, sowie MetaMask, eine Browser-Wallet zur Interaktion mit dem Netzwerk. Für die Entwicklung selbst liefert Remix IDE 1 eine vollständige webund desktopbasierte Lösung, Bereitstellung, Debugging und Testen von Smart Contracts. Ein Vorteil von Remix ist, dass die Gasgebühren von Smart Contracts direkt berechnet werden können. Darüber hinaus ermöglicht der Zugriff auf Bibliotheken wie web3.js und ethers.js 2die Interaktion mit Ethereum und erweitert damit die Möglichkeiten. 1Remix Projekt 2web3.js und ethers.js 28 4. Implementierung - Techniken für effiziente Smart Contracts Dieses Kapitel beschreibt ein praktische Aspekte für die Implementierung von Smart Contracts. Es wird kurz die Remix IDE erläutert und ein einfaches Beispiel für einen Smart Contract gegeben. Anschließend werden wichtige Grundlage im Kontext der Sicherheit und Effizienz bei der Implentierung von Smart Contract erläutert und ggf. die Gaskosten analysiert. In Bezug zu einigen erwähnten Implementierungsmethoden werden dann ausgewählte Patterns vorgestellt und abschließend auf die Best Practices der Smart Contract Implementierung eingegangen. 4.1. Einführung 4.1.1. Funktionsumfang der Remix IDE Abbildung 4.1.: Screenshot Remix IDE Die Remix IDE unterstützt den gesamten Prozess von der Erstellung und Kompilierung bis zur Bereitstellung und Interaktion mit Smart Contracts und bietet umfassende Tools zum Debuggen, Testen und Analysieren. Sie bietet dafür eine Vielzahl von Tools und Modulen, die sich in folgende Bereiche gliedern: •Hauptmodule wie Datei-Explorer, Plugin-Manager, Terminal und Editor. 29 4. Implementierung - Techniken für effiziente Smart Contracts •Solidity-Module einschließlich Compiler, Debugger und Analysatoren. •Unit Testing durch Plugins und Bibliotheken wie Chai und Mocha. •Integration externer Tools wie Hardhat, Truffle und Slither. •Anleitungen zur Erstellung und Bereitstellung von Contracts und Debugging. •Zusätzliche Funktionen wie Vyper-Unterstützung und Community-Support. [35] 4.1.2. Smart Contract Programmierung Smart Contracts in Solidity ähneln Klassen der objektorientierten Sprachen. Persistente Daten werden in Zustandsvariablen gespeichert und Funktionen können diese Variablen ändern. Funktionsaufrufe auf einem anderen Contract führen zu einem EVM-Funktionsaufruf und ändern den Kontext, sodass die Zustandsvariablen im aufrufenden Contracts unzugänglich sind. Verträge und Funktionen müssen explizit aufgerufen werden, damit etwas passiert. Es gibt keine automatischen Funktionsaufrufe (Cron-Jobs) in Ethereum. Jeder Contract kann Deklarationen von Zustandsvariablen, Funktionen, Modifiern, Events, Fehlern, Structs und Enums enthalten. Es gibt auch spezielle Arten von Contracts, wie libraries und interfaces . [12] Die Erstellung von Smart Contracts ist von außen über Transaktionen möglich oder innerhalb der SolidityContracts. Browserbasierte IDEs wie Remix unterstützen den Entwicklungsprozess mithilfe von UI-Elementen. Eine Möglichkeit, Verträge auf Ethereum programmatisch zu erstellen, ist die JavaScript-API web3.js. Sie verfügt über eine Funktion namens web3.eth.Contract , die die Erstellung von Verträgen erleichtert. Wenn ein Contract erstellt wird, wird sein Konstruktor (Schlüsselwort constructor ) einmal ausgeführt. Ein Konstruktor ist optional und nur ein Konstruktor ist erlaubt, d.h. Überladung wird nicht unterstützt. Nach dem Konstruktoraufruf wird der endgültige Code des Contracts in der Blockchain gespeichert. Der Code umfasst alle public - und external - Funktionen, sowie alle Funktionen, die von dort aus erreichbar sind. Er enthät nicht den Konstruktorcode oder internal -Funktionen, die nur von Konstruktor aufgerufen werden. Wenn ein Smart Contract einen anderen Smart Contract erstellen will, muss der Quellcode (und die Binärdatei) des erstellten Smart Contracts dem Ersteller bekannt sein, d.h. zyklische Abhängigkeiten sind bei der Erstellung unmöglich. [32] Die Solidity-Dokumentation ist zu finden auf https://soliditylang.org/. 30 4. Implementierung - Techniken für effiziente Smart Contracts 4.1.3. Beispiel Smart Contract RemixAI Es ist möglich, die RemixAI via Kommandozeilenbefehl sol-gpt nach einem einfachen Smart Contract Beispiel zu fragen. Folgender HelloWorld -Contract zeigt einen einfachen Aufbau eines Smart Contracts: 1// SPDX - License - Identifier : MIT 2pragma solidity >=0.4.22 < 0.9.0; 3 4contract HelloWorld { 5 6string private message ; 7 8event MessageSet ( string oldMessage , string newMessage ); 9 10 constructor () { 11 setMessage (" Hello World " , msg. sender ); 12 } 13 14 function setMessage ( string memory newMessage , address _sender ) internal { 15 // Only allow the contract to call this function (self - call ) 16 require ( _sender == tx. origin , " Only the contract itself can call this function ."); 17 18 string memory oldMessage = message ; 19 20 if( bytes ( newMessage ). length > 0){ 21 message = newMessage ; 22 23 emit MessageSet ( oldMessage , newMessage ); 24 } 25 } 26 } Listing 4.1: HelloWorld.sol Erläuterung zum Contract: Das Smart Contract-Beispiel 4.1 wird als Contract mit dem Namen HelloWorld definiert und enthält die zwei Funktionen getMessage() und setMessage() . Wenn ein leerer String als Nachricht gesetzt wird, wird die Transaktion rückgängig gemacht und ein Fehler ausgegeben. Beim Ändern der Nachricht wird ein Ereignis ausgelöst. Funktionen und Daten, die in den Contracts gesammelt werden, sind der Zustand. Es werden Zustandsvariablen definiert, wie hier message als String. Die Werte der Zustandsvariablen werden dauerhaft im Contractspeicher hinterlegt und entsprechende Schlüsselwörter wie public, private, internal definieren den Zugriff. Der Konstruktor wird verwendet, um die Contractdaten zu initialisieren. 31 4. Implementierung - Techniken für effiziente Smart Contracts Abbildung 4.2.: Gaskosten von Remix am Beispiel HelloWorld.sol 4.1.4. Token-Standards Die Implementierungen auf der Ethereum-Blockchain profitieren von verschiedenen ERC-Standards, die spezifische Vorteile bieten, sogenannten Token. Der ERC-20-TokenStandard zeichnet sich durch seine Effizienz bei Transaktionen aus, wodurch schnellere Bestätigungen und eine effiziente Interaktionen mit anderen Tokens ermöglicht werden. Er fördert somit einheitliche und schnelle Transaktionen und bietet damit eine verbesserte Effizienz im Blockchain-Ökosystem [22]. NFTs (Non-Fungible Tokens) oder auch ERC-721-Token bieten eine hohe Sicherheit und einzigartige Identität für digitale Assets. Der ERC-1155-Token kombiniert die Vorteile von ERC-20 und ERC-721, indem er verschiedene Token-Typen innerhalb eines Smart Contracts unterstützt. Diese Kombination optimiert nicht nur die Effizienz der Transaktionen, sondern auch die Sicherheit, indem separate Smart Contracts reduziert und Transaktionen gebündelt werden. [7] Die Vorteile des ERC20-Token-Systems im Überblick: • Einheitliche und schnelle Transaktionen • Effizientere Transaktionsbestätigungen • Die in ERC-20 implementierte Funktion hilft dem Web-Client, effizienter und schneller mit anderen Token und der Blockchain zu interagieren [16] Die Spezifikation der ERC-20 Schnittstelle in Solidity sieht folgendermaßen aus. Tokens können gaseffizient sein, müssen es aber nicht. Ein Beispiel für ein gaseffizientes Vertragsdesign ist der ERC-1155-Token-Standard. Er bietet eine vielseitige und kostengünstige Lösung für die Verwaltung mehrerer Token-Typen innerhalb eines einzigen Contracts.[14] 32 4. Implementierung - Techniken für effiziente Smart Contracts 4.1.5. Events and Logs Events und Logs sind essentielle Komponenten von Smart Contracts und bieten Einblick in die Funktionsweise, da sie bestimmte Zustände oder Aktivitäten, die während der Ausführung eines Smart Contracts auftreten, protokollieren. Sie werden in SolidityCode geschrieben und als Funktionen implementiert. Sie sind eine zuverlässige Quelle für die Nachverfolgung und Fehlersuche und sind deswegen unerlässlich, um potentielle Sicherheitsprobleme zu erkennen. Events dienen zur Erfassung von Ereignissen und sind eine praktische Schnittstelle, die von der EVM zur Verfügung gestellt wird. Sie ermöglichen es, Informationen in die Blockchain zu schreiben, die gut analysierbar und gaseffizienter sind, als das Speichern in öffentlichen Speichervariablen in Smart Contracts. Immer wenn ein Ereignis ausgelöst wird, wird das Protokoll in die Blockchain geschrieben. Es gibt drei Hauptverwendungszwecke von Events und Logs • Smart Contracts nutzen Events, um Werte an der Benutzeroberfläche wiederzugeben • Asynchrone Datentrigger, z.B. kann ein Event verwendet werden, wenn eine Zahlung erfolgt ist, um die externe Datenquelle zu aktualisieren. • Kostengünstiger Speicher, im Vergleich zu Memory, Storage und Calldata, siehe 4.3 [37, 6, 11] Logs in Solidity sind eine spezielle Datenstruktur sowie ein spezieller Speichermechanismuss für Events. Smart Contracts können nicht direkt auf sie zugreifen. Sie dienen dazu, die Leistung und Nutzung eines Smart Contracts zu verfolgen und geben Auskunft darüber, was in Transaktionen und Blöcken stattfindet. Durch ihre Unzugänglichkeit für Smart Contracts sind sie billiger zu emittieren. Durch die Überwachung der Logs kann der Code optimiert und sichergestellt werden, dass der Smart Contract so effizient wie möglich läuft. Der zugehörige Opcode lautet LOGn. [6, 11] Abbildung 4.3.: Logs https://www.ethervm.io/ Logs Gaskosten Logs kosten weniger als Contract Storage. Jedes Byte der Logs kostet 8 Gas, während eine Variable im Contract Storage 20.000 Gas für 32-Bytes kostet. [37] 33 4. Implementierung - Techniken für effiziente Smart Contracts • Daten können geändert werden IPFS: große Daten • Die Verwendung von Daten in Smart Contracts ist kompliziert • Die Änderung von Daten ist kompliziert [23, 37] Verwendung von Adressen mit vielen führenden Nullen Wenn zwei Adressen viele Nullen haben, z. B. 0x000000a4323... und 0x0000000000f38210 , dann können beide Adressen aufgrund der Nullen in denselben Speicherplatz gepackt werden. Um die Adressen zu verwenden, müssen lediglich die erforderlichen Nullen vorangestellt werden. Dies spart beispielsweise beim Überprüfen des Eigentümers eines Smart Contracts Speicherplatz. 4.2.3. Optimierung Kontrollstrukturen - for-Schleifen Inkrementieren: ++i kostet weniger Gas als i++ oder i += 1 Die Verwendung von ++i ist gaseffizienter als i++ oder i += 1 bei der Inkrementierung einer ganzen Zahl ohne Vorzeichen (uint). Der Grund dafür ist, dass ++i als Vorinkrementierung billiger ist und etwa 5 Gas pro Iteration spart. Bei der Verwendung von i++ muss der Compiler eine temporäre Variable erstellen, um den ursprünglichen Wert von izurückzugeben, was zusätzliche Gaskosten verursacht. [36] for-Schleifen durch Zwischenspeicherung der Länge optimieren 1for (uint i = 0; i < length ; i ++) { 2// do something that doesn ’t change the value of i 3} Listing 4.6: For-Loop i Im Listing 4.6 liest der Compiler bei jeder Iteration die Arraylänge. Das Auslesen der Array-Länge kostet bei jeder Schleifeniteration 6 Gas, 3 für MLOAD und drei für die Platzierung auf dem Stack memory_offset . Das Zwischenspeichern der Arraylänge im Stack spart pro Interation in etwa 3 Gas. Storage Array eine zusätzliche SLOAD -Operation (d.h. 100 Gas zusätzlich und 3 Gas pro Iteration (EIP-2929) Memory Array ist dies ein zusätzlicher MLOAD -Vorgang (3 zusätzliche Einheiten Gas werden für jede Iteration außer der ersten Calldata Array zusätzlichecalldataload Operation (3 Gas) außer der ersten Eine effizienter Implementierung ist folgende mit Zwischenspeicherung der Arraylänge: 40 4. Implementierung - Techniken für effiziente Smart Contracts 1uint length = arr . length ; 2for (uint i = 0; i < length ; i ++) { 3// do something that doesn ’t change arr . length 4} Listing 4.7: For-Loop array Im der for -Schleife des Listings 4.8 wird die Operation SLOAD oder MLOAD oder CALLDATALOAD nur einmal aufgerufen und anschließend durch eine billige DUPn -Anweisung ersetzt. Obwohl MLOAD , CALLDATALOAD und DUPN die gleichen Gaskosten haben, benötigen MLOAD und CALLDATALOAD ein zusätzliches DUPn , um den Offset auf den Stack zu legen, d.h. es werden 3 zusätzliche Gas verwendet. Diese Optimierung ist wichtig, wenn es sich um ein Storage Array oder eine lange for-Schleife handelt. [36] 1// SPDX - License - Identifier : MIT 2pragma solidity ^0.8.0; 3 4contract GasSavings { 5uint256 [] public storageArray ; 6 7constructor ( uint256 size ) { 8 9for ( uint256 i = 0; i < size; i++) { 10 storageArray .push(i); 11 } 12 } 13 14 // ohne Zwischenspeicherung der Arraylaenge 15 function withoutCaching () public view returns ( uint256 sum) { 16 for ( uint256 i = 0; i < storageArray . length ; i ++) { 17 sum += storageArray [i]; 18 } 19 } 20 21 // mit Zwischenspeicherung der Arraylaenge 22 function withCaching () public view returns ( uint256 sum ) { 23 uint256 length = storageArray . length ; 24 for ( uint256 i = 0; i < length; i++) { 25 sum += storageArray [i]; 26 } 27 } 28 } Listing 4.8: GasSavings.sol Die Methode withoutCaching() kostet 29114 Gas. Bei withCaching() betragen die Gaskosten 30167 Gas. Durch das Zwischenspeichern der Arraylänge in withCaching() konnten etwa 1053 Gas(0,0310EUR 10.11.2024) eingespart werden, was besonders bei umfangreicheren Arrays und häufig wiederkehrenden Berechnungen zu signifikanten Einsparungen führen kann. 41 4. Implementierung - Techniken für effiziente Smart Contracts Größe von storageArray withCaching() withoutCaching()) 10 29114 30167 100 255103 265769 Tabelle 4.6.: Kostenvergleich Zwischenspeicherung der Array-Länge withCaching() und withoutCaching() Verwendung von <= in der Schleifenbedingung 1function vanilla_loop () public pure returns ( uint256 sum ) { 2for ( uint256 n = 0; n < 100; n ++) { 3sum += n; 4} Listing 4.9: vanilla_loop() 1function loop_lte () public returns ( uint256 sum ) { 2for(uint256 n = 0; n <= 99; n ++) { 3sum += n; 4} 5} Listing 4.10: loop_lte() Im obigen Vergeich wurde die Schleifenbedingung von n < 100 zu n <= 99 geändert, was eine geringfügige Erhöhung der Gaskosten verursacht. Der Grund ist, dass <= im Vergleich zu < etwas mehr Berechnungen erfordert, was sich in höheren Gaskosten niederschlägt. Die Funktion mit <= kostet mehr Gas. Grund dafür ist, dass HighLevel-Solidity-Code in EVM-Bytecode kompiliert werden muss, um in Blockchain ausgeführt werden zu können. Die EVM die Opcodes für die Vergleiche LT , GT , und EQ , aber es gibt keine geeigneten LTEoder GTE-Opcodes für die Operation, die wir durchführen. Daher müssen jedes Mal, wenn die Bedingung n <= 99 geprüft wird, drei Anweisungen ausgeführt werden: LT n 99, EQ n 99, und OR, um zu prüfen, ob eine der beiden Antworten wahr ist. Funktion Ausführungskosten (in Gas) vanilla_loop() 25262 loop_unchecked_plusplus() 25328 Tabelle 4.7.: Vergleich der Ausführungskosten der Funktionen vanilla_loop() und loop_unchecked_plusplus() 42 4. Implementierung - Techniken für effiziente Smart Contracts Inkrement in unchecked Block Seit Version 0.8.n implementiert Solidity Sicherheitsprüfungen für alle Integer-Arithmetiken, einschließlich Overflowund Underflow. Dies ist gut für die Sicherheit von Smart Contracts, aber schlecht für den Gasverbrauch. Beim Postinkrement n++ fügt Solidity zusätzlichen Code ein, falls n nach der Inkrementierung überlaufen würde. Dies ist in Fällen nutzlos, in denen man weiß, dass die Schleifenbedingung garantiert, dass n niemals über 100 liegen und auch nicht 2 256 überschreiten wird. In solchen Fälle ist es sinnvoll, die Schleife in einen unchecked -Block verpacken, damit die Überlaufprüfung überspringen und damit Gas gespart wird. 1function loop_unchecked_plusplus () public returns ( uint256 sum ) { 2for ( uint256 n = 0; n < 100;) { 3sum += n; 4unchecked { 5n++; 6} 7} 8} Listing 4.11: loop_unchecked_plusplus() Es ist auch möglich die gesamte for -Schleife in den ungeprüften unchecked -Block zu packen. Aber nur, wenn man sicher weiß, dass die Variablen niemals überlaufen werden!!! Die Logik des Programmcodes sollte kritisch betrachtet werden, bevor man den gesamten Code ungeprüft lässt. 1function loop_unchecked () public returns ( uint256 sum ) { 2unchecked { 3for(uint256 n = 0; n < 100;) { 4sum += n; 5n++; 6} 7} 8} Listing 4.12: loop_unchecked() [28] Funktion Ausführungskosten loop_unchecked_plusplus() 25328 loop_unchecked() 7406 Tabelle 4.8.: Kostenvergleich loop_unchecked_plusplus() und loop_unchecked() 4.2.4. Funktionsparameter und Speicherverwaltung Nutzung von calldata anstatt memory für Funktionsparameter Manchmal ist es besser Funkionsargumente in calldata anstatt im memory -Speicher zu haben. Wenn Argumente bei externen Funktionen schreibgeschützt sind, sollte der 43 4. Implementierung - Techniken für effiziente Smart Contracts Datenort calldata sein. 1// SPDX - License - Identifier : MIT 2pragma solidity ^0.8.0; 3 4contract CMemory { 5function add( uint [] memory arr) external pure returns ( uint sum ) { 6uint length = arr . length ; 7for ( uint i = 0; i < length ;) { 8sum += arr [i]; 9unchecked { ++i; } 10 } 11 } 12 } Listing 4.13: CMemory.sol Das dynamische Array 4.13 hat den Speicherort memory . Bei Funktionsaufruf werden die Array-Werte in calldata gehalten und während der ABI-Dekodierung in den Speicher kopiert (unter Verwendung der Opcodes CALLDATALOAD und MSTORE ). Während der for-Schleife greift arr[i] mit MLOAD auf den Wert im Speicher zu. Für das obige Beispiel ist dies jedoch ineffizient. 1// SPDX - License - Identifier : MIT 2pragma solidity ^0.8.0; 3 4contract CCalldata { 5function add( uint [] calldata arr) external pure returns ( uint sum) { 6uint length = arr . length ; 7for (uint i = 0; i < length ;) 8sum += arr[i]; 9unchecked { ++i; } 10 } 11 } 12 } Listing 4.14: Calldata.sol In Listing 4.14 wird der Wert nicht über den Speicher, sondern direkt aus calldata mit dem Opcaode CALLDATALOAD gelesen. Das heißt, es gibt keine zwischengeschalteten Speicheroperationen, die diesen Wert übertragen. Ersparnis: Im ersten Beispiel beginnt die ABI-Dekodierung mit dem Kopieren des Wertes von calldata in den Speicher in einer for-Schleife. Jede Iteration würde mindestens 60 Gas kosten. Im zweiten Beispiel kann dies vollständig vermieden werden. Dadurch verringert sich auch die Anzahl der Anweisungen und damit die Kosten für die Einsatzzeit des Smart Contracts. [23] Wenn das Funktionsargument nur gelesen wird -calldata verwenden anstatt memory. 44 4. Implementierung - Techniken für effiziente Smart Contracts Array-Eingabe CMemory Ausführungs CCalldata Transaktions Differenz [1, 2, 3, 4, 5] 3670 2148 1522 [1, 2, 3,..., 10] 6265 3608 2657 [1, 2, 3,..., 20] 11456 6528 4928 [1, 2, 3,...,100] 52996 29888 23108 [1, 2, 3,...,1000] 522051 292688 229363 Tabelle 4.9.: Kostenvergleich CMemory.add(...) und CCalldata.add(...) mit den jeweiligen GasDifferenzen. 4.2.5. Effiziente Operationen und Berechnungen Effiziente Bit-Operationen: Shift-Anweisungen als Alternative zu Division und Multiplikation Eine Division/Multiplikation durch eine beliebige Zahl x, die eine Potenz von 2 ist, kann durch Verschiebung von log2(x) nach rechts/links berechnet werden. Während der DIV -Opcode 5 Gas verbraucht, benötigt der SHR -Opcode nur 3 Gas. Zusätzlich umfasst die Divisionsoperation von Solidity auch eine Verhinderung der Division durch 0, die durch Verschiebung umgangen wird. [23] Nicht strikte Ungleichhheit >= günstiger als > Der Vergleichsoperator „größer-gleich“ >= ist günstiger als der „größer“-Vergleich > . Dies ist auf einige zusätzliche Prüfungen zurückzuführen (ISZERO, 3 Gas). 1// SPDX - License - Identifier : MIT 2pragma solidity ^0.8.0; 3 4contract CheckStrict { 5uint256 public gas; 6function checkStrict () external { 7gas = gasleft (); 8gas -= gasleft (); 9} 10 function checkNonStrict() external { 11 gas = gasleft (); 12 require (999999999999999999 >= 1) ; 13 gas -= gasleft (); 14 } 15 } Listing 4.15: CheckStrict.sol Transaktionskosten Ausführungskosten checkStrict() 26645 5593 checkNonStrict() 26639 5575 Tabelle 4.10.: Kostenvergleich von den Funktionen checkStrict() und checkNonStrict() Bei nicht strikter Ungleichheit kann man eine Ersparnis von ca. 20 Gas erzielen [1]. 45 4. Implementierung - Techniken für effiziente Smart Contracts Verwendung doppelter require-Anweisungen statt des &&-Operators 1// SPDX - License - Identifier : MIT 2pragma solidity ^0.8.0; 3 4contract Require { 5uint256 public gas; 6 7function check1 ( uint x) public { 8gas = gasleft (); 9require (x == 0 && x < 1 ); 10 gas -= gasleft (); 11 } 12 13 function check2 ( uint x) public { 14 gas = gasleft (); 15 require (x == 0) ; 16 require (x < 1) ; 17 gas -= gasleft (); 18 } 19 } Listing 4.16: Requires.sol [23] Funktion Transaktionskosten Ausführungskosten Require.check1() (Eingabe: 0) 44145 22953 Require.check2() (Eingabe: 0) 27081 5889 Tabelle 4.11.: Kostenvergleich Require.check1() und Require.check2() 46 4. Implementierung - Techniken für effiziente Smart Contracts modifier anstelle von function Beispiel für zwei Contracts mit einer modifier -Funktion anstatt internal view -Funktion. 1// SPDX - License - Identifier : MIT 2pragma solidity 0.8.9; 3 4contract Inlined { 5function isNotExpired ( bool _true ) internal view { 6require ( _true == true , " Exchange : EXPIRED "); 7} 8function foo ( bool _test ) public returns ( uint ){ 9isNotExpired ( _test ); 10 return 1; 11 } 12 } Listing 4.17: Inlined.sol 1// SPDX - License - Identifier : MIT 2pragma solidity 0.8.9; 3 4contract Modifier { 5modifier isNotExpired ( bool _true ) { 6require ( _true == true , " Exchange : EXPIRED "); 7_; 8} 9function foo ( bool _test ) public isNotExpired ( _test ) returns ( uint ){ 10 return 1; 11 } 12 } Listing 4.18: Modifier.sol In der folgenden Tabelle zeigt sich, dass der Einsatz von modifier in diesem Beispiel etwa 24 Gas einspart. Allerdings sollte berücksichtigt werden, dass modifier die Codegröße des Smart Contracts ebenfalls erhöht. [36] Bedingung Ausführungskosten Transaktionskosten modifier.foo inline.foo modifier.foo inline.foo true 626 650 21830 21854 false 718 733 21910 21925 Tabelle 4.12.: Kostenvergleich modifierund internal view-Funktion 47 4. Implementierung - Techniken für effiziente Smart Contracts 4.2.6. Sonstige Optimierung Batching Durch das Batching können die Gaskosten gesenkt werden, da die übliche Datenverarbeitung reduziert werden kann. Codebeispiel: 1Old : func once ( uint256 header , uint256 val ...) x N 2New : func batch ( uint256 header , uint256 [] val ... x N) Listing 4.19: Batching Wenn wir die old -Funktion n -mal ausführen, wird das gemeinsame Feld header n-mal verarbeitet und die Funktion wird n-mal aufgerufen. Bei der Verwendung von Batching wird die Funktion jedoch nur einmal aufgerufen und das gemeinsame header wird nur einmal verarbeitet. Batching spart durch Speicherzuweisung und Funktionsaufrufe mittels CALLDATALOAD Gas. Je größer n ist, desto größer sind auch die Einsparungen. [37] Interne Funktionsaufrufe Das Listing 4.5 zeigt zwei internal -Funktionen. Diese können nur innerhalb des gleichen Contracts aufgerufen werden. Die Effizienz eines Smart Contracts hängt nicht nur von der Logik ab, die er ausführt, sondern auch davon, wie er seine Ressourcen verwaltet. Wenn ein Contract häufig seine eigenen öffentlichen Funktionen aufruft, ist das ineffizient. Denn diese Aufrufe sind teurer als interne Aufrufe, da die Parameter der öffentlichen Funktionen in den Speicher kopiert werden und dami den Gasverbrauch erhöhen. [26] 48 4. Implementierung - Techniken für effiziente Smart Contracts 4.3. Best Practices und Patterns Das Verständnis bestimmter Patterns hilft Entwicklern effiziente Smart Contracts zu erstellen. Hier werden zwei kurz erläutert. 4.3.1. Tight Variable Packing-Pattern Enges Packen von Variablen optimiert den Gasverbrauch beim Speichern oderLaden statisch dimensionierter Variablen. Das Muster beschreibt, wie man durch die Verwendung kleinerer Datentypen Gas sparen kann. Hintergrund ist, dass die EVM bestimmte Daten zusammen in einem Slot speichern kann. Es wird Speicherplatz gespart und Lesesowie Schreibzugriffe können in einer einzigen Operation zusammengefasst werden [29]. 4.3.2. Memory Array Building-Pattern Das Memory Array Building-Pattern ermöglicht das Aggregieren und Abrufen von Daten aus dem Contractspeicher auf gaseffiziente Weise. Das Memory array BuildingPattern findet Anwendung, • aggregierte Daten aus dem Speicher abgerufen werden • beim Abrufen von Daten keine Gaskosten entstehen sollen • die Daten Attribute haben, die sich ändern können Das Speichern eines Contracts gehört zu den teuersten Operationen. Das Senken von Gaskosten ist durch eine Variabledeklarierung mittels public möglich. Das führt dazu, dass im Hintergrund ein Getter erstellt wird, der freien Zugriff auf den Wert der Variablen ermöglicht. [29] Wenn jedoch Daten aus mehreren Quellen zusammengefasst werden sollen, würde dies eine Menge Lesevorgänge aus dem Speicher erfordern und somit kostspielig sein. Durch dieses Muster wird der view -Modifikator in Solidity genutzt, der es ermöglicht Daten aus dem Contractsspeicher zu aggregieren und zu lesen, ohne dass dadurch Kosten entstehen. Wenn ein Lookup neu angefordert wird, wird ein Array im Speicher neu aufgebaut, anstatt es im Speicher zu persistieren In Solidity ist die vorgeschlagene Lösung effizienter, da Funktionen mit dem view -Modifikator nicht in den Speicher schreiben dürfen, d.h. der Zustand der Blockchain wird nicht verändert. Alle Daten, die für die Ausführung dieser Funktionen erforderlich sind, sind lokal gespeichert. Ein Transaktion an das Netzwerk zu senden ist nicht nötig, da der Zustand der Blockchain unverändert bleibt. Der Prozess zur Speicherung und Abfrage von Daten lässt sich in zwei Hauptschritten zusammenfassen: Im ersten Schritt wird für die Speicherung der Daten eine Datenstruktur gewählt, die einfach zu iterieren ist. Hierfür eignet sich ein Array oder bei mehreren Attributen pro Datensatz eine Struct, um alle Attribute kompakt zu verwalten. Indem man ein Array aus solchen Structs erstellt, erhält jedes Element die notwendigen Attribute und kann einfach angesprochen werden. Ein weiteres wichtiges Element ist 49 5. Teststrategien und -umgebungen für Smart Contracts dezentrale Anwendungsentwicklung von Smart Contracts. Es ist offen für Benutzer, die Testnet-Validatoren betreiben möchten. Goerli ist veraltet und wurde 2023 von Holešky ersetzt. 8 Testnetzwerke sind Netzwerke, die von Protokollentwicklern oder Smart-Contract-Entwicklern genutzt werden, um sowohl Protokoll-Upgrades als auch potenzielle Smart Contracts in einer produktionsähnlichen Umgebung zu testen, bevor sie auf das Mainnet übertragen werden. Analogie: Produktionsund Staging-Server [24] Man kann Test-Ether über „Faucets “erhalten, um Transaktionen durchzuführen. MetaMask und andere Wallets können mit Testnetzwerken verbunden werden. Hardhat enthält das Hardhat Network, einen lokalen Ethereum-Netzwerkknoten, der speziell für die Entwicklung konzipiert ist. Damit ist es möglich, Smart Contracts bereitzustellen, Tests durchzuführen sowie zu debuggen – alles auf dem lokalen Rechner. 9 5.3. Testmethoden Es ist notwendig umfassende Tests durchzuführen, um Funktionalität, Sicherheit und Performance sicherzustellen. Im Zusammenhang mit Gasoptimierung sind insbesondere Tests des Gasverbrauchs von zentraler Bedeutung. Die wichtigsten Testmethoden umfassen: 5.3.1. Performancetests für Gasverbrauch Die Performancetests für Gasverbrauch messen die Effizienz eines Smart Contracts, insbesondere den Gasverbrauch bei verschiedenen Funktionsaufrufen. Diese Tests sind von entscheidender Bedeutung, um sicherzustellen, dass die Kosten für die Ausführung der Funktionen nicht unnötig hoch sind. Ein zu hoher Gasverbrauch kann einen ansonsten funktionierenden Contract unbrauchbar machen oder zu überhöhten Kosten führen. In diesen Tests werden Gaslimits überwacht und Schwellenwerte definiert, bei deren Überschreitung der Contract Fehler zurück gibt oder die Berechnungen nicht fortgeführt werden. Spezifische Testmethoden für Gasverbrauch Für die genaue Messung des Gasverbrauchs gibt es mehrere spezialisierte Methoden: •Direktes Messen im Testnetzwerk: In Testnetzwerken wie Sepolia oder Goerli können Entwickler den Gasverbrauch realer Transaktionen messen, um festzustellen, wie viel Gas eine Funktion im Vergleich zu anderen benötigt. •Verwendung von Hardhat Plugins: Mit Tools wie dem Hardhat Gas Reporter Plugin können detaillierte Berichte über den Gasverbrauch einzelner Funktionsaufrufe erstellt werden. Diese Berichte helfen dabei, Funktionen zu identifizieren, die zu viel Gas verbrauchen. 8https://github.com/eth-clients/holesky 9Hardhat Dokumentation 56 5. Teststrategien und -umgebungen für Smart Contracts •Simulierte Transaktionen: Entwickler können simulierte Transaktionen durchführen, bei denen die Gasgebühren und das Gaslimit überwacht werden, um zu testen, ob der Contract innerhalb akzeptabler Kosten bleibt. z.B. Remix, Hardhat, Truffle 5.3.2. CICD Durch kontinuierliche Integration, Continous Integration (CI), kann man Änderungen im Gasverbrauch bei jedem Commit überwachen, sofern Gastests im CI/CDProzess eingebunden sind. Automatisierte Tests validieren den Code in jeder Phase, von einzelnen Einheiten bis hin zu vollständigen Integrationen und stellen sicher, dass Änderungen die bestehende Funktionalität (Regression) nicht beeinträchtigen. Bei Blockchain-DevOpssind Tests für Smart Contracts besonders wichtig, da diese nach der Bereitstellung unveränderbar sind. Bei Smart Contracts wird durch automatisierte Tests sichergestellt, dass die Logik des Contracts solide und sicher ist, wodurch das Risiko kostspieliger Fehler in der Blockchain-Umgebung verringert wird. [8] 57 6. Bewertung der Ergebnisse Die EVM ist eine komplexe Ausführungsumgebung insbesondere durch die verschiedenen Speicher und weißt dadruch einige Herausforderungen hinsichtlich der Effizienz auf. Sich über die Funktionsweise im Klaren zu sein, ist besonders hilfreich bei der Implementierung von Smart Contracts. Die folgenden Aspekte lohnen sich dabei besonders und sind im Vergleich zu anderen Optimierungsmaßnahmen entscheidende Faktoren für die Effizienz von Smart Contracts: 1. Komprimierung von Variablen Solc Assembler Durch die Verwendung spezifisch angepasster Datentypen können Speicherplätze effizient genutzt und somit unnötige Speicheroperationen vermieden werden. Um die hohen Gaskosten der SSTORE-Operation zu reduzieren, können Variablen in structs auf 256-Bit-Slots optimiert angeordnet werden. Durch die Komprimierung wird die Anzahl der SSTORE-Operationen reduziert. 2. Optimierung von Kontrollstrukturen und Schleifen Bei der Strukturierung von Kontrollmechanismen und Schleifen sind Optimierungen wie die Verwendung von ++i statt i++ hilfreich, da sie den Gasverbrauch bei wiederholten Berechnungen reduzieren. Die Zwischenspeicherung der Schleifenlänge ist ein weiteres Beispiel, das die Effizienz erhöht, indem unnötige Berechnungen vermieden werden. 3. Nutzung von calldata anstatt memory für Funktionsparameter Gerade Speicheroperationen im permanenten storage -Bereich sind kostspielig, während der memory - und stack -Speicher für temporäre Daten weniger Gas benötigen. 4. Verwendung doppelter require-Anweisungen statt des &&-Operators Ein bemerkenswerter Unterschied in den Gaskosten konnte auch durch die Verwendung doppelter require -Anweisungen anstelle des &&-Operators erzielt werden. Indem die Logik in separate Prüfungen aufgeteilt wird, kann der Gasverbrauch deutlich gesenkt werden, da jede Bedingung einzeln bewertet und unnötige Rechenoperationen vermieden werden. 58 7. Fazit 7.1. Zusammenfassung In dieser Arbeit wurde aufgezeigt, welche Methoden zur Gasoptimierung in Smart Contracts führen. Es wurde hervorgehoben, wie unterschiedliche Datentypen und Speicherbereiche, wie storage, memory, calldata und logs, Einfluss auf die Gas-Kosten haben und wann welcher Typ am effizientesten eingesetzt werden sollte. Die Wahl der Speicherstruktur und die Nutzung geeigneter Datentypen sind entscheidend, um unnötige Gas-Kosten zu vermeiden. Zudem wurden Möglichkeiten zur Optimierung von Kontrollstrukturen und Funktionsparametern beschrieben, die besonders bei der Skalierung und bei komplexen Berechnungen innerhalb der Blockchain nützlich sind. Schließlich liefert die Arbeit Einblicke in Best Practices und Patterns, die dabei helfen können, Smart Contracts auf Ethereum effizient und kostengünstig zu gestalten, ohne dabei die Sicherheit und Funktionalität zu beeinträchtigen. Die Optimierung des Gasverbrauchs ist für Smart Contracts ein Thema, da sie nicht nur die Transaktionskosten direkt beeinflusst, sondern auch die Attraktivität und Effizienz von DApps erhöht. Die Arbeit hat gezeigt, dass Techniken wie die gezielte Auswahl des Speichertyps, die Verwendung von calldata anstelle von memory für Funktionsparameter und die Implementierung von Schleifen mit ungeprüften Blöcken signifikante Gaseinsparungen ermöglichen. Diese in „Bewertung der Ergebnisse“genannte Methoden haben sich als besonders effektiv erwiesen, um den Rechenaufwand und den Speicherbedarf zu reduzieren, ohne die Funktionalität zu beeinträchtigen. Obwohl Optimierungen wie ungeprüftes Inkrementieren und Batching in vielen Fällen sinnvoll sind, erfordern sie fundierte Kenntnisse und eine sorgfältige Abwägung der Sicherheitsrisiken. Darüber hinaus können bestimmte Optimierungen, wie die Reduzierung des Speicherplatzes für Variablen, auch die Lesbarkeit und Wartbarkeit des Codes erschweren, was für die langfristige Nutzbarkeit von Smart Contracts berücksichtigt werden muss. Die verschiedenen Techniken zur Optimierung der Gaskosten für Ethereum erfordern bei bestimmten Strategien ein hohes Maß an technischem und fachlichem Verständnis. Um effizient Smart Contracts zu schreiben ist es sinnvoll, die Gaskosten mit geeigeneten Tools vorher zu schätzen. In den Fällen des unchecked -Inkrements oder for -Schleifen, kann man zwar Gas sparen, muss sich aber auch um die möglichen Nachteile bei der Sicherheit im Klaren sein. Gerade Speicheroperationen im permanenten storage -Bereich sind kostspielig, während der memoryund stack-Speicher für temporäre Daten weniger Gas benötigen. 59 7. Fazit 7.2. Beantwortung der Fragestellung Die Implementierung von Smart Contracts für DApps auf EVMs erfordert ein solides Verständnis der EVM-Architektur. Gaspreise unterliegen starken Schwankungen, was zusätzlich zur Implementierung die Ausführungskosten für Smart Contracts dynamisch beeinflusst. Die Optimierungsstrategien sind daher hilfreich für die Senkung der Transaktionskosten und die Verbesserung der Effizienz. Im Rahmen der Untersuchung wurden zentrale Optimierungstechniken identifiziert, wie die Wahl der Speicherstruktur (z.B. storage, memory, calldata), der Einsatz gasoptimierter Kontrollstrukturen, die optimale Nutzung von Datentypen sowie effiziente Funktionsaufrufe und -parameter. Es wurde gezeigt, dass durch gezielte Optimierungsmaßnahmen teilweise erhebliche Gaseinsparungen möglich sind. Auch gibt es Gaseinsparungsmöglichkeiten, die die Sicherheit gefährden. 7.2.1. Best Practices Je einfacher der Code, desto weniger fehleranfällig ist er bekanntlich. Gibt es bereits geeignete Librariers oder Contracts, die den Anforderungen entsprechen, sollten diese genutzt bzw. wiederverwendet werden.Bereits getesteter und (oft) verwenderter Code ist ggf. sicherer als neue eigene Funktionen oder Libraries zu schreiben. Es gilt immer zu bedenken, dass Probleme die einmal gestarteter Code auf der Blockchain verursacht, schwer behoben werden können. Der Code sollte natürlich klar und nachvollziehbar sein, da er einmal veröffentlicht von jedem gelesen werden kann. Contracts laufen auf einer öffentlichen Blockchain, wo jeder sie mit beliebiegen Eingabewerten ausführen kann. [3] Es existiert eine ausführliche Knowledge Liste mit Best Practices im Repository: 1 Best Practices für die Gasoptimierung: • Gaslimits setzen • Vermeidung unnötiger Änderungen von Zustandsvariablen • Reduzierung von Zustandsänderungen, wenn sie nicht unbedingt erforderlich sind • Verwendung lokaler Variablen in Betracht ziehen • Ungenutzten oder redundanten Code entfernen • Verwenden Sie Modifikatoren anstelle von sich wiederholenden Codemustern ( mittels Modifikatoren können Codestücke einmal definiert werden.) auf mehrere Funktionen angewendet werden • Minimieren des benötigten Speicherplatz: storage -Speicheroperationen sind teurer als memory -Speicheroperationen. Eine Möglichkeit, den Speicherbedarf eines Smart Contracts zu minimieren, ist ein Design, das lokale Variablen und temporären Speicher bevorzugt. Dies reduziert die Notwendigkeit für dauerhafte Speicherzugriffe (storage) [36] 1https://github.com/guylando/KnowledgeLists/blob/master/EthereumSmartContracts.md 60 7. Fazit Durch diese Herangehensweisen und Best Practices konnte in dieser Arbeit gezeigt werden, dass eine Optimierung von Smart Contracts eine signifikante Rolle für die Reduktion von Gaskosten und die Effizienzsteigerung von DApps spielt. Die Ergebnisse verdeutlichen, dass die Berücksichtigung dieser Prinzipien bei der Entwicklung von Smart Contracts die Leistung und Kosten senkt. 7.3. Ausblick Weiterführende Untersuchungen zur Optimierung und Sicherheit von Smart Contracts sind ein weiteres spannendes Gebiet. Angesichts der fortlaufenden Anpassungen der Gaskosten durch Hardforks bleiben nicht alle Strategien dauerhaft effektiv, somit können mit jeder Änderung neue, verbesserte Ansätze erforderlich werden. Generell kann übermäßige Optimierung die Lesbarkeit und Wartbarkeit des Codes beeinträchtigen. Einige fortgeschrittene Techniken erfordern tiefes Verständnis der EVM-Architektur, wie die Assemblervariante der Variablenkomprimierung. Eine Analyse der Auswirkungen solcher Optimierungen auf die Sicherheit wäre insbesondere für fortgeschrittene Techniken interessant.. 61 Quellenverzeichnis [1] 262588213843476. Solidity gas optimizations and tricks. en. url: https://gist. github.com/grGred/9bab8b9bad0cd42fc23d4e31e7347144 (besucht am 02.11. 2024). [2] Joel Adewole. A developers guide to Solidity design patterns. Juli 2022. url: https: / / blog . logrocket . com / developers - guide - solidity - design - patterns/ (besucht am 10.11. 2024). [3] Gavin Wood Andreas M. Antonopoulos. EthereumGrundlagen und ProgrammierungSmart Contracts und DApps entwickeln. 1.Auflage. Heidelberg: O’Reilly, 2019. isbn: 978-3-96009-110-3. [4] Andreas M. Antonopoulos. Bitcoin BlockchainGrundlagen und Programmierung. 2.Auflage, 2018. Heidelberg: O’Reilly, 2018. isbn: 978-3-96009-110-3. [5] Henri Arslanian. The Book of Crypto: The Complete Guide to Understanding Bitcoin, Cryptocurrencies and Digital Assets. en. Cham: Springer International Publishing, 2022. isbn: 978-3-030-97950-8 978-3-030-97951-5. doi: 10.1007/978-3-030-979515 .url: https://link.springer.com/10.1007/978-3-030-97951-5 (besucht am 01.11. 2024). [6] Kuuku Baffoe. Understanding Solidity Events and Logs. en. [Zugriff 02.07.2024]. März 2023. url: https://medium.com/coinmonks/understanding-solidityevents-and-logs-f29ea4f557cc (besucht am 02.07.2024). [7] Bitpanda. ERC20: Standard für Token des Ethereum-Netzwerks. de-DE. url: https: //www.bitpanda.com/academy/de/lektionen/was-ist-der-erc20-tokenstandard (besucht am 13.07. 2024). [8] Blockchain and DevOps for Your Business. en. url: https://rpcfast.com/blog/ blockchain-devops (besucht am 09.11. 2024). [9] Enée Bussac. Blockchain und digitale Währungen: Auf dem Weg zur Echtzeit-Wirtschaft. de. Berlin: Erich Schmidt Verlag GmbH & Co. KG, 2023. isbn: 978-3-503-20697-1. doi: 10.37307/b.978-3-503-20697-1 .url: https://esv-elibrary.de/book/ 99.160005/9783503206971 (besucht am 16.10. 2024). [10] Vitalik Buterin. „Ethereum: A Next-Generation Smart Contract and Decentralized Application Platform.“ en. In: (). (Besucht am 10.07.2024). [11] Chainlink. Events and Logging in SoliditySolidity Events and Logging [With Examples] | Chainlink. en-US. Nov. 2021. url: https://blog.chain.link/events-andlogging-in-solidity/ (besucht am 02.07.2024). [12] Solidity Documentation. Structure of a Contract — Solidity 0.8.27 documentation.url: https://docs.soliditylang.org/en/develop/structure-of-a-contract. html (besucht am 11.07. 2024). [13] Daniel Drescher. Blockchain Grundlagen: eine Einführung in die elementaren Konzepte in 25 Schritten. de. Übers. von Guido Lenz. 1. Auflage. Frechen: mitp, 2017. isbn: 978-3-95845-654-9 978-3-95845-653-2. 62 Quellenverzeichnis [14] Metana Editorial. What are Ethereum Gas Fees: A Comprehensive Guide. en-US. Section: Blockchain. Jan. 2024. url: https : / / metana . io / blog / what - are - ethereum-gas-fees/ (besucht am 16.11.2024). [15] Einführung in den Ethereum-Stack. de. url: https://ethereum.org/de/developers/ docs/ethereum-stack/ (besucht am 23.10. 2024). [16] ERC-20 Token-Standard. de. url: https://ethereum.org/de/developers/docs/ standards/tokens/erc-20/ (besucht am 24.07. 2024). [17] Ethereum Virtual Machine (EVM). de. url: https://ethereum.org/de/developers/ docs/evm/ (besucht am 10.11. 2024). [18] ethereumbook/06transactions.asciidoc at develop · ethereumbook/ethereumbook.url: https://github.com/ethereumbook/ethereumbook/blob/develop/06transactions. asciidoc (besucht am 07.10. 2024). [19] EVM Codes. en. url:https://www.evm.codes (besucht am 18.07. 2024). [20] EVM CodesAbout the EVM. en. url: https://www.evm.codes/about (besucht am 30.10. 2024). [21] Daniel Hellwig, Goran Karlic und Arnd Huchzermeier. Entwickeln Sie Ihre eigene Blockchain: Ein praktischer Leitfaden zur Distributed-Ledger-Technologie. de. Berlin, Heidelberg: Springer Berlin Heidelberg, 2021. isbn: 978-3-662-62965-9 978-3-66262966-6. doi: 10.1007/978-3-662-62966-6 .url: https://link.springer.com/ 10.1007/978-3-662-62966-6 (besucht am 16.04.2024). [22] Flo Krause. ERC20 Token Standard einfach erklaert. de-DE. Jan. 2019. url: https: //blockchainwelt.de/erc20-token-ethereum-einfach-erklaert/ (besucht am 01.11. 2024). [23] Zhichao Li. Techniques to Cut Gas Costs for Your Dapps. en. Dez. 2023. url: https://medium.com//techniquestocutgascostsforyourdapps7e8628c56fc9 (besucht am 02.11. 2024). [24] Netzwerke. de. url: https://ethereum.org/de/developers/docs/networks/ (besucht am 17.11. 2024). [25] Alexander Schill und Thomas Springer. Verteilte Systeme: Grundlagen und Basistechnologien. de. eXamen.press. Berlin, Heidelberg: Springer Berlin Heidelberg, 2012. isbn: 978-3-642-25795-7 978-3-642-25796-4. doi: 10.1007/978-3-642-25796-4 . url: https://link.springer.com/10.1007/978-3-642-25796-4 (besucht am 26.10. 2024). [26] Smart Contract Mastery: Solidity Patterns for Enhanced Gas Efficiency Recash Lab. en-US. url: https://recash.tech/2024/03/03/smart-contractmasterysolidity-patterns-for-enhanced-gas-efficiency/ (besucht am 09.11. 2024). [27] Smart Contracts.url: https://www.fon.hum.uva.nl/rob/Courses/InformationInSpeech/ CDROM/Literature/LOTwinterschool2006/szabo.best.vwh.net/smart.contracts. html (besucht am 28.10. 2024). [28] Solidity Gas Optimization Techniques: Loops. de. url: https://hackmd.io/@totomanov/ gas-optimization-loops (besucht am 10.11.2024). [29] Solidity Patterns. en-US. url: https://fravoll.github.io/solidity-patterns/ (besucht am 10.11. 2024). 63 Quellenverzeichnis [30] solidity-patterns/docs/memory_array_building.md at master fravoll/solidity-patterns. url: https://github.com/fravoll/solidity-patterns/blob/master/docs/ memory_array_building.md (besucht am 10.11. 2024). [31] Solidity — Solidity 0.8.26 documentation. [Zugriff 29.06.2024]. url: https://docs. soliditylang.org/en/v0.8.26/ (besucht am 29.06. 2024). [32] Solidity — Solidity 0.8.26 documentation. [Zugriff 30.06.2024]. url: https://docs. soliditylang.org/en/latest/contracts.html (besucht am 29.06. 2024). [33] Spritgebühren auf Ethereum: Wie funktionieren sie? de. url: https://ethereum.org/ de/gas/ (besucht am 10.07. 2024). [34] André Schweizer Vincent Schlatt. BLOCKCHAIN: GRUNDLAGEN, ANWENDUNGEN UND POTENZIALE. de. url: https://www.fit.fraunhofer.de/content/ dam/fit/de/documents/Blockchain_WhitePaper_Grundlagen-AnwendungenPotentiale.pdf (besucht am 14.06. 2024). [35] Welcome to Remixs documentation! Remix - Ethereum IDE 1 documentation.url: https://remix-ide.readthedocs.io/en/latest/ (besucht am 31.10. 2024). [36] Vladislav Yaroshuk. Solidity Gas Optimizations Tricks. en. Dez. 2022. url: https: / / betterprogramming . pub / solidity - gas - optimizations - and - tricks - 2bcee0f9f1f2 (besucht am 02.11. 2024). [37] Gavin Zheng u. a. Ethereum Smart Contract Development in Solidity. en. Singapore: Springer Singapore, 2021. isbn: 9789811562174 9789811562181. doi: 10.1007/978981-15-6218-1 .url: http://link.springer.com/10.1007/978-981-15-62181(besucht am 26.10. 2024). 64 8. Abkürzungsverzeichnis ABI Application Binary Interface DApp Dezentralized App DeFi Dezentrale Finance DLT Distributed Ledger Technologie DHT Distributed Hash Table EOA Externally Owned Account ETH Abkürzung für Ether IPFS InterPlanetary File System NFT Non-fungible-Token P2P Peer to Peer RPC Remote Procedure Call SOLC Solidity Compiler 65