[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-18-evm-bytecode-debuggen-traces":3},{"article":4,"author":55},{"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":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":35,"related_articles":36},"d7000000-0000-0000-0000-000000000118","a0000000-0000-0000-0000-000000000072","Deep EVM #18: EVM-Bytecode debuggen — Traces, Stack-Dumps und cast run","deep-evm-18-evm-bytecode-debuggen-traces","EVM-Bytecode-Debugging mit cast run fuer Transaktionsnachspielung, forge debug fuer Schritt-fuer-Schritt-Analyse und Techniken zum Lesen roher Opcode-Traces meistern.","## Debugging auf Bytecode-Ebene\n\nWenn eine Solidity-Transaktion revertiert, erhalten Sie typischerweise eine beschreibende Fehlermeldung. Wenn eine Huff- oder Yul-Transaktion revertiert, erhalten Sie ein leeres Revert-Payload ohne Kontext. Debugging auf Bytecode-Ebene erfordert andere Werkzeuge und mentale Modelle.\n\n## cast run: Transaktionen nachspielen\n\n`cast run` ist das maechtigste Debugging-Werkzeug fuer On-Chain-Transaktionen:\n\n```bash\n# Transaktion nachspielen mit vollstaendigem Trace\ncast run 0x1234...abcd --rpc-url mainnet -vvvv\n\n# Nur den Trace einer bestimmten Adresse anzeigen\ncast run 0x1234...abcd --rpc-url mainnet -vvvv \\\n  --label 0xContract:MyContract\n```\n\nDie Ausgabe zeigt jeden Opcode, den Stack-Zustand und Gasverbrauch:\n\n```\n[0] PUSH1 0x80\n    Stack: [0x80]\n    Gas: 499979\n[2] PUSH1 0x40\n    Stack: [0x80, 0x40]\n    Gas: 499976\n[4] MSTORE\n    Stack: []\n    Gas: 499964\n```\n\n## forge debug: Interaktiver Debugger\n\n```bash\n# Test im Debug-Modus starten\nforge debug test\u002FMyTest.t.sol --sig \"testSwap()\"\n\n# Bestimmte Transaktion debuggen\nforge debug --fork-url mainnet 0x1234...abcd\n```\n\nDer interaktive Debugger ermoeglicht:\n- Schritt-fuer-Schritt durch Opcodes navigieren\n- Stack und Memory zu jedem Zeitpunkt inspizieren\n- Breakpoints an bestimmten Programmzaehlern setzen\n- Storage-Aenderungen verfolgen\n\n## Haeufige Debugging-Szenarien\n\n### 1. Leerer Revert\nProblem: Transaktion revertiert ohne Fehlermeldung.\n\nLoesung:\n```bash\n# Trace analysieren — suche den letzten REVERT-Opcode\ncast run 0x... -vvvv | grep -A5 \"REVERT\"\n```\n\nHaeufige Ursachen:\n- Stack-Unterlauf (Opcode versucht, mehr zu entnehmen als vorhanden)\n- JUMPDEST-Fehler (Sprung zu einer Position ohne JUMPDEST)\n- Gaserschoepfung in einem Unteraufruf\n\n### 2. Falsches Ergebnis\nProblem: Contract gibt falschen Wert zurueck.\n\nLoesung: Stack-Zustand vor RETURN pruefen:\n```bash\n# RETURN-Opcode finden und Memory inspizieren\ncast run 0x... -vvvv | grep -B10 \"RETURN\"\n```\n\n### 3. Out-of-Gas\nProblem: Transaktion laeuft aus dem Gas.\n\nLoesung:\n```bash\n# Gas-Verbrauch pro Opcode analysieren\ncast run 0x... -vvvv | awk '\u002FGas:\u002F {print $NF}' | sort -n\n```\n\n## Opcode-Trace lesen\n\nEin typischer Trace fuer einen ERC-20-Transfer:\n\n```\n\u002F\u002F Funktionsselektor laden\nPUSH1 0x00 CALLDATALOAD  \u002F\u002F [calldata[0:32]]\nPUSH1 0xe0 SHR           \u002F\u002F [selector]\n\n\u002F\u002F Gegen transfer(address,uint256) pruefen\nDUP1 PUSH4 0xa9059cbb EQ \u002F\u002F [selector==transfer, selector]\nPUSH2 0x00a4 JUMPI       \u002F\u002F Springe wenn match\n\n\u002F\u002F Bei transfer:\nJUMPDEST                  \u002F\u002F \u003C- Sprungziel\nPUSH1 0x04 CALLDATALOAD  \u002F\u002F [to_address]\nPUSH1 0x24 CALLDATALOAD  \u002F\u002F [amount, to_address]\n```\n\n## Debugging-Checkliste fuer Huff\n\n1. Stack-Kommentare in jedem Makro pruefen\n2. `takes()` und `returns()` Deklarationen verifizieren\n3. Jeden externen Aufruf mit cast run nachverfolgen\n4. Gas-Budget pro Pfad mit forge test --gas-report analysieren\n5. Differentielles Testen gegen Solidity-Referenz durchfuehren\n6. Edge Cases testen: leere Calldata, maximale Werte, Reentrancy\n\n## Fazit\n\nEVM-Bytecode-Debugging ist eine Kunst, die Uebung erfordert. cast run und forge debug sind Ihre wichtigsten Werkzeuge. Der Schluessel: Verstehen Sie den Stack-Zustand zu jedem Zeitpunkt der Ausfuehrung, und Sie werden jedes Problem loesen koennen.","\u003Ch2 id=\"debugging-auf-bytecode-ebene\">Debugging auf Bytecode-Ebene\u003C\u002Fh2>\n\u003Cp>Wenn eine Solidity-Transaktion revertiert, erhalten Sie typischerweise eine beschreibende Fehlermeldung. Wenn eine Huff- oder Yul-Transaktion revertiert, erhalten Sie ein leeres Revert-Payload ohne Kontext. Debugging auf Bytecode-Ebene erfordert andere Werkzeuge und mentale Modelle.\u003C\u002Fp>\n\u003Ch2 id=\"cast-run-transaktionen-nachspielen\">cast run: Transaktionen nachspielen\u003C\u002Fh2>\n\u003Cp>\u003Ccode>cast run\u003C\u002Fcode> ist das maechtigste Debugging-Werkzeug fuer On-Chain-Transaktionen:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\"># Transaktion nachspielen mit vollstaendigem Trace\ncast run 0x1234...abcd --rpc-url mainnet -vvvv\n\n# Nur den Trace einer bestimmten Adresse anzeigen\ncast run 0x1234...abcd --rpc-url mainnet -vvvv \\\n  --label 0xContract:MyContract\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Die Ausgabe zeigt jeden Opcode, den Stack-Zustand und Gasverbrauch:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>[0] PUSH1 0x80\n    Stack: [0x80]\n    Gas: 499979\n[2] PUSH1 0x40\n    Stack: [0x80, 0x40]\n    Gas: 499976\n[4] MSTORE\n    Stack: []\n    Gas: 499964\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"forge-debug-interaktiver-debugger\">forge debug: Interaktiver Debugger\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-bash\"># Test im Debug-Modus starten\nforge debug test\u002FMyTest.t.sol --sig \"testSwap()\"\n\n# Bestimmte Transaktion debuggen\nforge debug --fork-url mainnet 0x1234...abcd\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Der interaktive Debugger ermoeglicht:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Schritt-fuer-Schritt durch Opcodes navigieren\u003C\u002Fli>\n\u003Cli>Stack und Memory zu jedem Zeitpunkt inspizieren\u003C\u002Fli>\n\u003Cli>Breakpoints an bestimmten Programmzaehlern setzen\u003C\u002Fli>\n\u003Cli>Storage-Aenderungen verfolgen\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"haeufige-debugging-szenarien\">Haeufige Debugging-Szenarien\u003C\u002Fh2>\n\u003Ch3>1. Leerer Revert\u003C\u002Fh3>\n\u003Cp>Problem: Transaktion revertiert ohne Fehlermeldung.\u003C\u002Fp>\n\u003Cp>Loesung:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\"># Trace analysieren — suche den letzten REVERT-Opcode\ncast run 0x... -vvvv | grep -A5 \"REVERT\"\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Haeufige Ursachen:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Stack-Unterlauf (Opcode versucht, mehr zu entnehmen als vorhanden)\u003C\u002Fli>\n\u003Cli>JUMPDEST-Fehler (Sprung zu einer Position ohne JUMPDEST)\u003C\u002Fli>\n\u003Cli>Gaserschoepfung in einem Unteraufruf\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>2. Falsches Ergebnis\u003C\u002Fh3>\n\u003Cp>Problem: Contract gibt falschen Wert zurueck.\u003C\u002Fp>\n\u003Cp>Loesung: Stack-Zustand vor RETURN pruefen:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\"># RETURN-Opcode finden und Memory inspizieren\ncast run 0x... -vvvv | grep -B10 \"RETURN\"\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>3. Out-of-Gas\u003C\u002Fh3>\n\u003Cp>Problem: Transaktion laeuft aus dem Gas.\u003C\u002Fp>\n\u003Cp>Loesung:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\"># Gas-Verbrauch pro Opcode analysieren\ncast run 0x... -vvvv | awk '\u002FGas:\u002F {print $NF}' | sort -n\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"opcode-trace-lesen\">Opcode-Trace lesen\u003C\u002Fh2>\n\u003Cp>Ein typischer Trace fuer einen ERC-20-Transfer:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F Funktionsselektor laden\nPUSH1 0x00 CALLDATALOAD  \u002F\u002F [calldata[0:32]]\nPUSH1 0xe0 SHR           \u002F\u002F [selector]\n\n\u002F\u002F Gegen transfer(address,uint256) pruefen\nDUP1 PUSH4 0xa9059cbb EQ \u002F\u002F [selector==transfer, selector]\nPUSH2 0x00a4 JUMPI       \u002F\u002F Springe wenn match\n\n\u002F\u002F Bei transfer:\nJUMPDEST                  \u002F\u002F &lt;- Sprungziel\nPUSH1 0x04 CALLDATALOAD  \u002F\u002F [to_address]\nPUSH1 0x24 CALLDATALOAD  \u002F\u002F [amount, to_address]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"debugging-checkliste-fuer-huff\">Debugging-Checkliste fuer Huff\u003C\u002Fh2>\n\u003Col>\n\u003Cli>Stack-Kommentare in jedem Makro pruefen\u003C\u002Fli>\n\u003Cli>\u003Ccode>takes()\u003C\u002Fcode> und \u003Ccode>returns()\u003C\u002Fcode> Deklarationen verifizieren\u003C\u002Fli>\n\u003Cli>Jeden externen Aufruf mit cast run nachverfolgen\u003C\u002Fli>\n\u003Cli>Gas-Budget pro Pfad mit forge test –gas-report analysieren\u003C\u002Fli>\n\u003Cli>Differentielles Testen gegen Solidity-Referenz durchfuehren\u003C\u002Fli>\n\u003Cli>Edge Cases testen: leere Calldata, maximale Werte, Reentrancy\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"fazit\">Fazit\u003C\u002Fh2>\n\u003Cp>EVM-Bytecode-Debugging ist eine Kunst, die Uebung erfordert. cast run und forge debug sind Ihre wichtigsten Werkzeuge. Der Schluessel: Verstehen Sie den Stack-Zustand zu jedem Zeitpunkt der Ausfuehrung, und Sie werden jedes Problem loesen koennen.\u003C\u002Fp>\n","de","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:30.360094Z","EVM-Bytecode debuggen — Traces, Stack-Dumps und cast run","EVM-Bytecode-Debugging mit cast run, forge debug und roher Opcode-Trace-Analyse fuer Huff- und Yul-Smart-Contracts meistern.","EVM-Bytecode debuggen",null,"index, follow",[22,27,31],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000021","Foundry","foundry",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000017","Huff","huff","Blockchain",[37,43,49],{"id":38,"title":39,"slug":40,"excerpt":41,"locale":12,"category_name":35,"published_at":42},"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":44,"title":45,"slug":46,"excerpt":47,"locale":12,"category_name":35,"published_at":48},"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":50,"title":51,"slug":52,"excerpt":53,"locale":12,"category_name":35,"published_at":54},"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":56,"slug":57,"bio":58,"photo_url":19,"linkedin":19,"role":59,"created_at":60,"updated_at":60},"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"]