[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-18-otladka-evm-bajtkoda-trejsy-stek-dampy":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},"d0000000-0000-0000-0000-000000000218","a0000000-0000-0000-0000-000000000012","Deep EVM #18: Отладка EVM-байткода — трейсы, стек-дампы и cast run","deep-evm-18-otladka-evm-bajtkoda-trejsy-stek-dampy","Освойте отладку EVM-байткода: cast run для воспроизведения транзакций, forge debug для пошагового анализа и техники чтения сырых трейсов опкодов.","## Зачем нужна отладка на уровне байткода\n\nКогда Solidity-дебаггер бессилен — когда вы работаете с Huff, inline-ассемблером или анализируете неверифицированный контракт — единственный инструмент, который остаётся, это отладка на уровне EVM-байткода. Понимание того, как читать трейсы опкодов, интерпретировать стек-дампы и воспроизводить транзакции, превращает вас из разработчика смарт-контрактов в настоящего EVM-инженера.\n\nEVM — это стековая машина с 256-битными словами. Каждая инструкция читает из стека и\u002Fили записывает в стек. Когда транзакция завершается с revert, байткод не скажет «ошибка в строке 42» — вместо этого вы увидите последовательность опкодов, приведших к `REVERT`. Задача отладки — восстановить контекст.\n\n## cast run — воспроизведение транзакций\n\nFoundry's `cast run` позволяет воспроизвести любую историческую транзакцию с полным трейсом:\n\n```bash\ncast run 0xTRANSACTION_HASH --rpc-url https:\u002F\u002Feth.llamarpc.com -vvvv\n```\n\nФлаг `-vvvv` включает максимальную детализацию: каждый опкод, состояние стека, изменения памяти и хранилища.\n\nВывод включает:\n- **Дерево вызовов** — иерархия CALL, DELEGATECALL, STATICCALL\n- **Логи** — все эмитированные события\n- **Изменения состояния** — что именно записалось в storage\n- **Расход газа** — газ для каждого подвызова\n\n## forge debug — пошаговая отладка\n\n`forge debug` запускает интерактивный дебаггер с TUI-интерфейсом:\n\n```bash\nforge debug --debug test\u002FSimpleToken.t.sol \\\n  --sig \"test_transfer()\" -vvvv\n```\n\nИнтерфейс показывает:\n- Текущий опкод и program counter\n- Полное содержимое стека\n- Содержимое памяти (hex + ASCII)\n- Текущий calldata\n\nНавигация: `n` — следующий шаг, `s` — шаг внутрь вызова, `c` — продолжить до брейкпоинта.\n\n## Чтение сырых трейсов опкодов\n\nРассмотрим типичный фрагмент трейса:\n\n```\n[PUSH1] 0x04\n[CALLDATALOAD]\n[PUSH1] 0x00\n[MSTORE]\n[PUSH1] 0x20\n[PUSH1] 0x00\n[SHA3]\n[SLOAD]\n```\n\nЭто классический паттерн чтения значения из mapping: загружается ключ из calldata, записывается в память, хешируется через SHA3 (KECCAK256) для получения storage-слота, затем загружается значение через SLOAD.\n\nПонимание этих паттернов позволяет быстро ориентироваться в байткоде без исходного кода.\n\n## Декомпозиция revert-причин\n\nКогда транзакция откатывается, EVM может вернуть данные через revert. Стандартный формат ошибки Solidity:\n\n```\n0x08c379a0 — Error(string)\n0x4e487b71 — Panic(uint256)\n```\n\nДекодирование revert-данных:\n\n```bash\ncast 4byte-decode 0x08c379a0...\n```\n\nДля кастомных ошибок используйте `cast decode-error` с ABI контракта.\n\n## Практика: отладка реальной failed-транзакции\n\nРассмотрим пошаговый процесс:\n\n1. **Получите hash транзакции** — из эксплорера или логов\n2. **Воспроизведите с трейсом**: `cast run TX_HASH --rpc-url URL -vvvv`\n3. **Найдите точку revert** — ищите `REVERT` в выводе\n4. **Проанализируйте стек перед revert** — какие значения были на стеке?\n5. **Определите паттерн** — это проверка баланса? Проверка owner? Overflow?\n6. **Проверьте гипотезу** — воспроизведите с изменёнными параметрами\n\n## Инструменты для продвинутой отладки\n\n### Tenderly\nОблачный дебаггер с визуальным интерфейсом. Показывает state diff, gas breakdown, и позволяет симулировать транзакции с изменёнными параметрами.\n\n### evm.codes\nИнтерактивная справка по опкодам EVM. Для каждого опкода показывает потребление газа, эффект на стек и примеры использования.\n\n### hevm\nСимволический исполнитель EVM от DappTools. Позволяет находить входные данные, приводящие к определённому состоянию — мощный инструмент для поиска уязвимостей.\n\n## Отладка storage layout\n\nПонимание раскладки хранилища критично для отладки:\n\n```bash\n# Прочитать слот хранилища\ncast storage CONTRACT_ADDR 0 --rpc-url URL\n\n# Для mapping: вычислить слот\ncast keccak \\\n  $(cast abi-encode \"f(address,uint256)\" ADDR SLOT)\n```\n\nДля proxy-контрактов помните об EIP-1967 слотах:\n- Implementation: `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n- Admin: `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n\n## Заключение\n\nОтладка EVM-байткода — это навык, который отличает продвинутого блокчейн-разработчика. Инструменты Foundry — cast run и forge debug — делают этот процесс доступным. Регулярная практика чтения трейсов, понимание паттернов опкодов и знание storage layout позволят вам быстро диагностировать любые проблемы на уровне EVM.","\u003Ch2 id=\"\">Зачем нужна отладка на уровне байткода\u003C\u002Fh2>\n\u003Cp>Когда Solidity-дебаггер бессилен — когда вы работаете с Huff, inline-ассемблером или анализируете неверифицированный контракт — единственный инструмент, который остаётся, это отладка на уровне EVM-байткода. Понимание того, как читать трейсы опкодов, интерпретировать стек-дампы и воспроизводить транзакции, превращает вас из разработчика смарт-контрактов в настоящего EVM-инженера.\u003C\u002Fp>\n\u003Cp>EVM — это стековая машина с 256-битными словами. Каждая инструкция читает из стека и\u002Fили записывает в стек. Когда транзакция завершается с revert, байткод не скажет «ошибка в строке 42» — вместо этого вы увидите последовательность опкодов, приведших к \u003Ccode>REVERT\u003C\u002Fcode>. Задача отладки — восстановить контекст.\u003C\u002Fp>\n\u003Ch2 id=\"cast-run\">cast run — воспроизведение транзакций\u003C\u002Fh2>\n\u003Cp>Foundry’s \u003Ccode>cast run\u003C\u002Fcode> позволяет воспроизвести любую историческую транзакцию с полным трейсом:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">cast run 0xTRANSACTION_HASH --rpc-url https:\u002F\u002Feth.llamarpc.com -vvvv\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Флаг \u003Ccode>-vvvv\u003C\u002Fcode> включает максимальную детализацию: каждый опкод, состояние стека, изменения памяти и хранилища.\u003C\u002Fp>\n\u003Cp>Вывод включает:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Дерево вызовов\u003C\u002Fstrong> — иерархия CALL, DELEGATECALL, STATICCALL\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Логи\u003C\u002Fstrong> — все эмитированные события\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Изменения состояния\u003C\u002Fstrong> — что именно записалось в storage\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Расход газа\u003C\u002Fstrong> — газ для каждого подвызова\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"forge-debug\">forge debug — пошаговая отладка\u003C\u002Fh2>\n\u003Cp>\u003Ccode>forge debug\u003C\u002Fcode> запускает интерактивный дебаггер с TUI-интерфейсом:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">forge debug --debug test\u002FSimpleToken.t.sol \\\n  --sig \"test_transfer()\" -vvvv\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Интерфейс показывает:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Текущий опкод и program counter\u003C\u002Fli>\n\u003Cli>Полное содержимое стека\u003C\u002Fli>\n\u003Cli>Содержимое памяти (hex + ASCII)\u003C\u002Fli>\n\u003Cli>Текущий calldata\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Навигация: \u003Ccode>n\u003C\u002Fcode> — следующий шаг, \u003Ccode>s\u003C\u002Fcode> — шаг внутрь вызова, \u003Ccode>c\u003C\u002Fcode> — продолжить до брейкпоинта.\u003C\u002Fp>\n\u003Ch2 id=\"\">Чтение сырых трейсов опкодов\u003C\u002Fh2>\n\u003Cp>Рассмотрим типичный фрагмент трейса:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>[PUSH1] 0x04\n[CALLDATALOAD]\n[PUSH1] 0x00\n[MSTORE]\n[PUSH1] 0x20\n[PUSH1] 0x00\n[SHA3]\n[SLOAD]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Это классический паттерн чтения значения из mapping: загружается ключ из calldata, записывается в память, хешируется через SHA3 (KECCAK256) для получения storage-слота, затем загружается значение через SLOAD.\u003C\u002Fp>\n\u003Cp>Понимание этих паттернов позволяет быстро ориентироваться в байткоде без исходного кода.\u003C\u002Fp>\n\u003Ch2 id=\"revert\">Декомпозиция revert-причин\u003C\u002Fh2>\n\u003Cp>Когда транзакция откатывается, EVM может вернуть данные через revert. Стандартный формат ошибки Solidity:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>0x08c379a0 — Error(string)\n0x4e487b71 — Panic(uint256)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Декодирование revert-данных:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">cast 4byte-decode 0x08c379a0...\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Для кастомных ошибок используйте \u003Ccode>cast decode-error\u003C\u002Fcode> с ABI контракта.\u003C\u002Fp>\n\u003Ch2 id=\"failed\">Практика: отладка реальной failed-транзакции\u003C\u002Fh2>\n\u003Cp>Рассмотрим пошаговый процесс:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Получите hash транзакции\u003C\u002Fstrong> — из эксплорера или логов\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Воспроизведите с трейсом\u003C\u002Fstrong>: \u003Ccode>cast run TX_HASH --rpc-url URL -vvvv\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Найдите точку revert\u003C\u002Fstrong> — ищите \u003Ccode>REVERT\u003C\u002Fcode> в выводе\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Проанализируйте стек перед revert\u003C\u002Fstrong> — какие значения были на стеке?\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Определите паттерн\u003C\u002Fstrong> — это проверка баланса? Проверка owner? Overflow?\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Проверьте гипотезу\u003C\u002Fstrong> — воспроизведите с изменёнными параметрами\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">Инструменты для продвинутой отладки\u003C\u002Fh2>\n\u003Ch3>Tenderly\u003C\u002Fh3>\n\u003Cp>Облачный дебаггер с визуальным интерфейсом. Показывает state diff, gas breakdown, и позволяет симулировать транзакции с изменёнными параметрами.\u003C\u002Fp>\n\u003Ch3>evm.codes\u003C\u002Fh3>\n\u003Cp>Интерактивная справка по опкодам EVM. Для каждого опкода показывает потребление газа, эффект на стек и примеры использования.\u003C\u002Fp>\n\u003Ch3>hevm\u003C\u002Fh3>\n\u003Cp>Символический исполнитель EVM от DappTools. Позволяет находить входные данные, приводящие к определённому состоянию — мощный инструмент для поиска уязвимостей.\u003C\u002Fp>\n\u003Ch2 id=\"storage-layout\">Отладка storage layout\u003C\u002Fh2>\n\u003Cp>Понимание раскладки хранилища критично для отладки:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\"># Прочитать слот хранилища\ncast storage CONTRACT_ADDR 0 --rpc-url URL\n\n# Для mapping: вычислить слот\ncast keccak \\\n  $(cast abi-encode \"f(address,uint256)\" ADDR SLOT)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Для proxy-контрактов помните об EIP-1967 слотах:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Implementation: \u003Ccode>0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Admin: \u003Ccode>0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"\">Заключение\u003C\u002Fh2>\n\u003Cp>Отладка EVM-байткода — это навык, который отличает продвинутого блокчейн-разработчика. Инструменты Foundry — cast run и forge debug — делают этот процесс доступным. Регулярная практика чтения трейсов, понимание паттернов опкодов и знание storage layout позволят вам быстро диагностировать любые проблемы на уровне EVM.\u003C\u002Fp>\n","ru","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:23.904818Z","Отладка EVM-байткода — трейсы, стек-дампы и cast run","Отладка EVM-байткода с помощью cast run, forge debug и техник чтения сырых трейсов опкодов.","отладка evm байткод",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","Блокчейн",[37,43,49],{"id":38,"title":39,"slug":40,"excerpt":41,"locale":12,"category_name":35,"published_at":42},"de000000-0000-0000-0000-000000000013","Уровень интероперабельности Ethereum: как 55+ L2 становятся одной сетью","uroven-interoperabelnosti-ethereum-kak-55-l2-stanovyatsya-odnoj-setyu","У Ethereum 55+ роллапов Layer 2, фрагментирующих ликвидность и пользовательский опыт. Уровень интероперабельности Ethereum — объединяющий кросс-роллап-мессаджинг, общие секвенсоры и based-роллапы — призван объединить их в единую компонуемую сеть.","2026-03-28T10:44:36.068675Z",{"id":44,"title":45,"slug":46,"excerpt":47,"locale":12,"category_name":35,"published_at":48},"de000000-0000-0000-0000-000000000012","ZK-доказательства за пределами роллапов: верифицируемый AI-инференс на Ethereum","zk-dokazatelstva-za-predelami-rollapov-verificiruemyj-ai-inferens-ethereum","Доказательства с нулевым разглашением — это уже не только инструмент масштабирования. В 2026 году zkML обеспечивает верифицируемый AI-инференс в блокчейне, ZK-копроцессоры переносят тяжёлые вычисления оффчейн с ончейн-верификацией, а новые системы доказательств SP1 и Jolt делают это практичным.","2026-03-28T10:44:36.026310Z",{"id":50,"title":51,"slug":52,"excerpt":53,"locale":12,"category_name":35,"published_at":54},"dd000000-0000-0000-0000-000000000013","EIP-7702 на практике: создание потоков смарт-аккаунтов после Pectra","eip-7702-na-praktike-sozdanie-potokov-smart-akkauntov-posle-pectra","EIP-7702 позволяет любому EOA Ethereum временно действовать как смарт-контракт в рамках одной транзакции. Вот как реализовать пакетные транзакции, спонсирование газа и социальное восстановление с помощью нового примитива абстракции аккаунтов.","2026-03-28T10:44:35.357227Z",{"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"]