[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-2-speichermodell-stack-memory-storage-calldata":3},{"article":4,"author":54},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":34,"related_articles":35},"d7000000-0000-0000-0000-000000000102","a0000000-0000-0000-0000-000000000072","Deep EVM #2: Speichermodell — Stack, Memory, Storage und Calldata","deep-evm-2-speichermodell-stack-memory-storage-calldata","Ein tiefer Einblick in die vier Datenbereiche der EVM — Stack, Memory, Storage und Calldata — ihre Kosten, ihr Verhalten und die Speichererweiterungsformel, die Entwickler ueberrascht.","## Vier Datenbereiche der EVM\n\nDie EVM stellt vier unterschiedliche Datenbereiche bereit, jeder mit radikal unterschiedlichen Kosten, Lebensdauern und Zugriffsmustern. Die falsche Wahl ist die haeufigste Ursache fuer uebermassigen Gasverbrauch in Smart Contracts.\n\n### Stack\nDer Stack ist der primaere Arbeitsbereich der EVM. Er ist 1024 Elemente tief, wobei jedes Element 256 Bit breit ist. Der Zugriff auf den Stack ist kostenlos (im Gas-Sinne) — nur 3 Gas fuer DUP- und SWAP-Operationen. Aber der Stack hat eine entscheidende Einschraenkung: Sie koennen nur auf die obersten 16 Elemente zugreifen.\n\n### Memory (Arbeitsspeicher)\nMemory ist ein linearer Byte-Array, der bei Null beginnt und nach Bedarf waechst. Es ist fluechtig — nach Beendigung des Aufrufkontexts wird er verworfen. Der Zugriff erfolgt ueber MLOAD (32 Bytes lesen) und MSTORE (32 Bytes schreiben), jeweils fuer 3 Gas.\n\nDer Haken: Die **Speichererweiterungskosten** steigen quadratisch. Die erste Erweiterung ist billig, aber bei grossen Speichermengen explodieren die Kosten.\n\n```\n\u002F\u002F Speichererweiterungskosten-Formel:\n\u002F\u002F cost = 3 * words + words^2 \u002F 512\n\u002F\u002F wobei words = ceil(size \u002F 32)\n\n\u002F\u002F Beispiele:\n\u002F\u002F 32 Bytes (1 Wort):    3 Gas\n\u002F\u002F 1 KB (32 Woerter):    99 Gas\n\u002F\u002F 32 KB (1024 Woerter): 5120 Gas\n\u002F\u002F 1 MB:                 ~3 Millionen Gas\n```\n\n### Storage (Permanenter Speicher)\nStorage ist der permanente Speicher eines Contracts — er ueberlebt zwischen Transaktionen. Jeder Slot ist 256 Bit breit, adressiert durch einen 256-Bit-Schluessel. Storage ist bei weitem der teuerste Datenbereich:\n\n- Erster Schreibvorgang (0 -> ungleich Null): 22.100 Gas\n- Aenderung (ungleich Null -> ungleich Null): 5.000 Gas\n- Lesen: 2.100 Gas (kalt) \u002F 100 Gas (warm)\n\nWarum so teuer? Weil jeder Storage-Schreibvorgang von jedem Knoten im Ethereum-Netzwerk fuer immer gespeichert werden muss.\n\n### Calldata\nCalldata sind die schreibgeschuetzten Eingabedaten einer Transaktion. Sie koennen waehrend der Ausfuehrung nicht veraendert werden. Calldata sind guenstig: 16 Gas pro Nicht-Null-Byte, 4 Gas pro Null-Byte. Deshalb kodiert Solidity Funktionsargumente als Calldata.\n\n## Transient Storage (EIP-1153)\n\nEIP-1153 (Dencun-Upgrade, Maerz 2024) fuehrte einen fuenften Datenbereich ein: **Transient Storage**. Er verhielt sich wie normaler Storage, wird aber am Ende der Transaktion verworfen. Die neuen Opcodes TLOAD und TSTORE kosten nur 100 Gas — deutlich weniger als die 2.100\u002F22.100 des normalen Storage.\n\nDer primaere Anwendungsfall ist Reentrancy-Schutz. Das klassische Reentrancy-Lock erfordert einen SSTORE (teuer). Mit Transient Storage wird das Lock nach der Transaktion automatisch zurueckgesetzt, ohne dass Sie es manuell loeschen muessen.\n\n## Speicherlayout in Solidity\n\nDer Solidity-Compiler packt Zustandsvariablen in Storage-Slots nach bestimmten Regeln:\n\n- Variablen werden in der Reihenfolge ihrer Deklaration in aufeinanderfolgende Slots gepackt.\n- Wenn eine Variable in den verbleibenden Platz des aktuellen Slots passt, wird sie dort platziert.\n- Andernfalls wird ein neuer Slot begonnen.\n- Structs und Arrays beginnen immer einen neuen Slot.\n\n```solidity\ncontract StorageLayout {\n    \u002F\u002F Slot 0: [uint128 a | uint128 b] — gepackt!\n    uint128 a; \u002F\u002F 16 Bytes\n    uint128 b; \u002F\u002F 16 Bytes — passt in gleichen Slot\n    \n    \u002F\u002F Slot 1: uint256 c — belegt ganzen Slot\n    uint256 c;\n    \n    \u002F\u002F Slot 2: [bool d | address e] — 1 + 20 = 21 Bytes, gepackt\n    bool d;    \u002F\u002F 1 Byte\n    address e; \u002F\u002F 20 Bytes\n}\n```\n\nDas Verstaendnis des Storage-Layouts ist entscheidend fuer Gasoptimierung. Wenn zwei Variablen, die oft zusammen gelesen werden, in verschiedenen Slots liegen, zahlen Sie fuer zwei Storage-Lesevorgaenge statt einen.\n\n## Memory-Layout und Free Memory Pointer\n\nSolidity verwendet einen **Free Memory Pointer** bei Adresse 0x40, der auf das naechste freie Byte im Memory zeigt. Wenn Sie neuen Memory allozieren, inkrementiert der Compiler den Pointer.\n\n```\n\u002F\u002F Memory-Layout:\n\u002F\u002F 0x00 - 0x3f: Scratch-Space (temporaerer Arbeitsbereich)\n\u002F\u002F 0x40 - 0x5f: Free Memory Pointer\n\u002F\u002F 0x60 - 0x7f: Zero-Slot (immer Null, als Anfangswert fuer dynamische Arrays)\n\u002F\u002F 0x80 - ...:  Frei verfuegbarer Memory\n```\n\nIn Yul oder Assembly muessen Sie den Free Memory Pointer manuell verwalten. Wenn Sie ihn vergessen zu aktualisieren, ueberschreiben nachfolgende Allokationen Ihre Daten.\n\n## Praktische Optimierung: Datenbereich-Wahl\n\n1. **Verwenden Sie Calldata statt Memory fuer Funktionsargumente** — externe Funktionen mit `calldata`-Parametern sparen Gas, da keine Kopie in Memory erstellt wird.\n2. **Packen Sie Storage-Variablen** — ordnen Sie Variablen so an, dass sie in minimale Slots passen.\n3. **Cachen Sie Storage-Lesevorgaenge in lokalen Variablen** — ein kalter SLOAD kostet 2.100 Gas; ein Memory-Lesevorgang kostet 3 Gas.\n4. **Verwenden Sie Transient Storage fuer temporaere Flags** — Reentrancy-Locks, kurzfristige Zustandsflags.\n5. **Vermeiden Sie grosse Memory-Allokationen** — die quadratische Kostenerweiterung macht grosse Arrays extrem teuer.\n\n## Fazit\n\nDie vier Datenbereiche der EVM — Stack, Memory, Storage und Calldata — haben jeweils spezifische Eigenschaften und Kosten. Die richtige Wahl des Datenbereichs ist der wichtigste Faktor fuer die Gaseffizienz Ihres Smart Contracts. Verstehen Sie die Kosten, verstehen Sie die Einschraenkungen, und Ihre Contracts werden deutlich guenstiger in der Ausfuehrung.","\u003Ch2 id=\"vier-datenbereiche-der-evm\">Vier Datenbereiche der EVM\u003C\u002Fh2>\n\u003Cp>Die EVM stellt vier unterschiedliche Datenbereiche bereit, jeder mit radikal unterschiedlichen Kosten, Lebensdauern und Zugriffsmustern. Die falsche Wahl ist die haeufigste Ursache fuer uebermassigen Gasverbrauch in Smart Contracts.\u003C\u002Fp>\n\u003Ch3>Stack\u003C\u002Fh3>\n\u003Cp>Der Stack ist der primaere Arbeitsbereich der EVM. Er ist 1024 Elemente tief, wobei jedes Element 256 Bit breit ist. Der Zugriff auf den Stack ist kostenlos (im Gas-Sinne) — nur 3 Gas fuer DUP- und SWAP-Operationen. Aber der Stack hat eine entscheidende Einschraenkung: Sie koennen nur auf die obersten 16 Elemente zugreifen.\u003C\u002Fp>\n\u003Ch3>Memory (Arbeitsspeicher)\u003C\u002Fh3>\n\u003Cp>Memory ist ein linearer Byte-Array, der bei Null beginnt und nach Bedarf waechst. Es ist fluechtig — nach Beendigung des Aufrufkontexts wird er verworfen. Der Zugriff erfolgt ueber MLOAD (32 Bytes lesen) und MSTORE (32 Bytes schreiben), jeweils fuer 3 Gas.\u003C\u002Fp>\n\u003Cp>Der Haken: Die \u003Cstrong>Speichererweiterungskosten\u003C\u002Fstrong> steigen quadratisch. Die erste Erweiterung ist billig, aber bei grossen Speichermengen explodieren die Kosten.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F Speichererweiterungskosten-Formel:\n\u002F\u002F cost = 3 * words + words^2 \u002F 512\n\u002F\u002F wobei words = ceil(size \u002F 32)\n\n\u002F\u002F Beispiele:\n\u002F\u002F 32 Bytes (1 Wort):    3 Gas\n\u002F\u002F 1 KB (32 Woerter):    99 Gas\n\u002F\u002F 32 KB (1024 Woerter): 5120 Gas\n\u002F\u002F 1 MB:                 ~3 Millionen Gas\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Storage (Permanenter Speicher)\u003C\u002Fh3>\n\u003Cp>Storage ist der permanente Speicher eines Contracts — er ueberlebt zwischen Transaktionen. Jeder Slot ist 256 Bit breit, adressiert durch einen 256-Bit-Schluessel. Storage ist bei weitem der teuerste Datenbereich:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Erster Schreibvorgang (0 -&gt; ungleich Null): 22.100 Gas\u003C\u002Fli>\n\u003Cli>Aenderung (ungleich Null -&gt; ungleich Null): 5.000 Gas\u003C\u002Fli>\n\u003Cli>Lesen: 2.100 Gas (kalt) \u002F 100 Gas (warm)\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Warum so teuer? Weil jeder Storage-Schreibvorgang von jedem Knoten im Ethereum-Netzwerk fuer immer gespeichert werden muss.\u003C\u002Fp>\n\u003Ch3>Calldata\u003C\u002Fh3>\n\u003Cp>Calldata sind die schreibgeschuetzten Eingabedaten einer Transaktion. Sie koennen waehrend der Ausfuehrung nicht veraendert werden. Calldata sind guenstig: 16 Gas pro Nicht-Null-Byte, 4 Gas pro Null-Byte. Deshalb kodiert Solidity Funktionsargumente als Calldata.\u003C\u002Fp>\n\u003Ch2 id=\"transient-storage-eip-1153\">Transient Storage (EIP-1153)\u003C\u002Fh2>\n\u003Cp>EIP-1153 (Dencun-Upgrade, Maerz 2024) fuehrte einen fuenften Datenbereich ein: \u003Cstrong>Transient Storage\u003C\u002Fstrong>. Er verhielt sich wie normaler Storage, wird aber am Ende der Transaktion verworfen. Die neuen Opcodes TLOAD und TSTORE kosten nur 100 Gas — deutlich weniger als die 2.100\u002F22.100 des normalen Storage.\u003C\u002Fp>\n\u003Cp>Der primaere Anwendungsfall ist Reentrancy-Schutz. Das klassische Reentrancy-Lock erfordert einen SSTORE (teuer). Mit Transient Storage wird das Lock nach der Transaktion automatisch zurueckgesetzt, ohne dass Sie es manuell loeschen muessen.\u003C\u002Fp>\n\u003Ch2 id=\"speicherlayout-in-solidity\">Speicherlayout in Solidity\u003C\u002Fh2>\n\u003Cp>Der Solidity-Compiler packt Zustandsvariablen in Storage-Slots nach bestimmten Regeln:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Variablen werden in der Reihenfolge ihrer Deklaration in aufeinanderfolgende Slots gepackt.\u003C\u002Fli>\n\u003Cli>Wenn eine Variable in den verbleibenden Platz des aktuellen Slots passt, wird sie dort platziert.\u003C\u002Fli>\n\u003Cli>Andernfalls wird ein neuer Slot begonnen.\u003C\u002Fli>\n\u003Cli>Structs und Arrays beginnen immer einen neuen Slot.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cpre>\u003Ccode class=\"language-solidity\">contract StorageLayout {\n    \u002F\u002F Slot 0: [uint128 a | uint128 b] — gepackt!\n    uint128 a; \u002F\u002F 16 Bytes\n    uint128 b; \u002F\u002F 16 Bytes — passt in gleichen Slot\n    \n    \u002F\u002F Slot 1: uint256 c — belegt ganzen Slot\n    uint256 c;\n    \n    \u002F\u002F Slot 2: [bool d | address e] — 1 + 20 = 21 Bytes, gepackt\n    bool d;    \u002F\u002F 1 Byte\n    address e; \u002F\u002F 20 Bytes\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Das Verstaendnis des Storage-Layouts ist entscheidend fuer Gasoptimierung. Wenn zwei Variablen, die oft zusammen gelesen werden, in verschiedenen Slots liegen, zahlen Sie fuer zwei Storage-Lesevorgaenge statt einen.\u003C\u002Fp>\n\u003Ch2 id=\"memory-layout-und-free-memory-pointer\">Memory-Layout und Free Memory Pointer\u003C\u002Fh2>\n\u003Cp>Solidity verwendet einen \u003Cstrong>Free Memory Pointer\u003C\u002Fstrong> bei Adresse 0x40, der auf das naechste freie Byte im Memory zeigt. Wenn Sie neuen Memory allozieren, inkrementiert der Compiler den Pointer.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F Memory-Layout:\n\u002F\u002F 0x00 - 0x3f: Scratch-Space (temporaerer Arbeitsbereich)\n\u002F\u002F 0x40 - 0x5f: Free Memory Pointer\n\u002F\u002F 0x60 - 0x7f: Zero-Slot (immer Null, als Anfangswert fuer dynamische Arrays)\n\u002F\u002F 0x80 - ...:  Frei verfuegbarer Memory\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>In Yul oder Assembly muessen Sie den Free Memory Pointer manuell verwalten. Wenn Sie ihn vergessen zu aktualisieren, ueberschreiben nachfolgende Allokationen Ihre Daten.\u003C\u002Fp>\n\u003Ch2 id=\"praktische-optimierung-datenbereich-wahl\">Praktische Optimierung: Datenbereich-Wahl\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\u003Cstrong>Verwenden Sie Calldata statt Memory fuer Funktionsargumente\u003C\u002Fstrong> — externe Funktionen mit \u003Ccode>calldata\u003C\u002Fcode>-Parametern sparen Gas, da keine Kopie in Memory erstellt wird.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Packen Sie Storage-Variablen\u003C\u002Fstrong> — ordnen Sie Variablen so an, dass sie in minimale Slots passen.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Cachen Sie Storage-Lesevorgaenge in lokalen Variablen\u003C\u002Fstrong> — ein kalter SLOAD kostet 2.100 Gas; ein Memory-Lesevorgang kostet 3 Gas.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Verwenden Sie Transient Storage fuer temporaere Flags\u003C\u002Fstrong> — Reentrancy-Locks, kurzfristige Zustandsflags.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Vermeiden Sie grosse Memory-Allokationen\u003C\u002Fstrong> — die quadratische Kostenerweiterung macht grosse Arrays extrem teuer.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"fazit\">Fazit\u003C\u002Fh2>\n\u003Cp>Die vier Datenbereiche der EVM — Stack, Memory, Storage und Calldata — haben jeweils spezifische Eigenschaften und Kosten. Die richtige Wahl des Datenbereichs ist der wichtigste Faktor fuer die Gaseffizienz Ihres Smart Contracts. Verstehen Sie die Kosten, verstehen Sie die Einschraenkungen, und Ihre Contracts werden deutlich guenstiger in der Ausfuehrung.\u003C\u002Fp>\n","de","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:29.906470Z","Tiefer Einblick in das EVM-Speichermodell: Stack, Memory, Storage, Calldata, Transient Storage und die Speichererweiterungskostenformel.","EVM Speichermodell",null,"index, follow",[21,26,30],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":31,"name":32,"slug":33,"created_at":25},"c0000000-0000-0000-0000-000000000014","Solidity","solidity","Blockchain",[36,42,48],{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":34,"published_at":41},"d0000000-0000-0000-0000-000000000611","Die Ethereum-Interoperabilitaetsschicht: Wie 55+ L2s zu einer Chain werden","ethereum-interoperabilitaetsschicht-55-l2s-eine-chain","Ethereum hat 55+ Layer-2-Rollups, die Liquiditaet und Nutzererfahrung fragmentieren. Die Ethereum-Interoperabilitaetsschicht — bestehend aus Cross-Rollup-Messaging, Shared Sequencern und Based Rollups — zielt darauf ab, sie zu einem einzigen komponierbaren Netzwerk zu vereinen.","2026-03-28T10:44:45.264352Z",{"id":43,"title":44,"slug":45,"excerpt":46,"locale":12,"category_name":34,"published_at":47},"d0000000-0000-0000-0000-000000000610","ZK-Beweise jenseits von Rollups: Verifizierbare KI-Inferenz auf Ethereum","zk-beweise-jenseits-von-rollups-verifizierbare-ki-inferenz-ethereum","Zero-Knowledge-Beweise sind nicht mehr nur ein Skalierungswerkzeug. Im Jahr 2026 ermoeglicht zkML verifizierbare KI-Inferenz on-chain, ZK-Coprozessoren verlagern schwere Berechnungen off-chain mit On-Chain-Verifizierung, und neue Beweissysteme wie SP1 und Jolt machen es praktikabel.","2026-03-28T10:44:45.257775Z",{"id":49,"title":50,"slug":51,"excerpt":52,"locale":12,"category_name":34,"published_at":53},"d0000000-0000-0000-0000-000000000587","EIP-7702 in der Praxis: Smart-Account-Flows nach Pectra erstellen","eip-7702-in-der-praxis-smart-account-flows-nach-pectra-erstellen","EIP-7702 ermoeglicht jedem Ethereum-EOA, innerhalb einer einzelnen Transaktion voruebergehend als Smart Contract zu agieren. So implementieren Sie Batch-Transaktionen, Gas-Sponsoring und Social Recovery mit dem neuen Account-Abstraction-Primitiv.","2026-03-28T10:44:43.781201Z",{"id":13,"name":55,"slug":56,"bio":57,"photo_url":18,"linkedin":18,"role":58,"created_at":59,"updated_at":59},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]