[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-18-depuracion-bytecode-evm-trazas":3},{"article":4,"author":42},{"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":22,"related_articles":23},"d8000000-0000-0000-0000-000000000118","a0000000-0000-0000-0000-000000000082","Deep EVM #18: Depuración de Bytecode EVM — Trazas, Volcados de Stack y cast run","deep-evm-18-depuracion-bytecode-evm-trazas","Técnicas de depuración para bytecode EVM: trazas de ejecución con Foundry, volcados de stack paso a paso, análisis de transacciones fallidas con cast run, y herramientas de visualización.","## El reto de depurar bytecode\n\nCuando un contrato Huff o Yul falla, no hay mensajes de error legibles — solo un REVERT silencioso. La depuración de bytecode requiere herramientas especializadas que muestren el estado del stack, memoria y storage en cada paso.\n\n## Trazas de ejecución con Foundry\n\nFoundry proporciona trazas detalladas con el flag `-vvvv`:\n\n```bash\nforge test --match-test testTransfer -vvvv\n```\n\nLa salida muestra:\n```\n[PASS] testTransfer()\n  Traces:\n    [65432] HuffToken::transfer(alice, 100)\n      PUSH1 0x00\n      CALLDATALOAD\n      PUSH1 0xe0\n      SHR\n      ...\n      SSTORE [slot: 0x..., value: 900]\n      SSTORE [slot: 0x..., value: 100]\n      LOG3 (Transfer event)\n      RETURN\n```\n\n## cast run: análisis de transacciones on-chain\n\n`cast run` de Foundry reproduce una transacción con traza completa:\n\n```bash\n# Reproducir una transacción fallida\ncast run 0xABC123...DEF --rpc-url https:\u002F\u002Feth.llamarpc.com -vvvv\n\n# Con traza de opcodes\ncast run 0xABC123...DEF --debug\n```\n\nEsto es invaluable para entender por qué una transacción de un bot MEV falló en producción.\n\n## Depuración paso a paso\n\nFoundry incluye un debugger interactivo:\n\n```bash\nforge debug --debug src\u002Ftest\u002FMiTest.t.sol --sig \"testTransfer()\"\n```\n\nEl debugger muestra:\n- Estado del stack en cada opcode\n- Contenido de la memoria\n- Slots de storage modificados\n- Gas restante\n- Programa counter y opcode actual\n\n## Análisis de reverts\n\nCuando un contrato revierte, el proceso de diagnóstico es:\n\n1. **Identificar el opcode REVERT** — ¿En qué posición del bytecode ocurre?\n2. **Trazar hacia atrás** — ¿Qué condición falló justo antes del REVERT?\n3. **Inspeccionar el stack** — ¿Los valores son los esperados?\n4. **Verificar calldata** — ¿Se decodificaron correctamente los parámetros?\n\n```solidity\n\u002F\u002F En tu test, captura el error:\nfunction testShouldRevert() public {\n    (bool ok, bytes memory returnData) = token.call(\n        abi.encodeWithSignature(\"transfer(address,uint256)\", address(0), 100)\n    );\n    \n    assertFalse(ok, \"Debe revertir para address(0)\");\n    \n    \u002F\u002F Decodificar datos de revert si los hay\n    if (returnData.length >= 4) {\n        bytes4 selector = bytes4(returnData);\n        emit log_named_bytes4(\"Error selector\", selector);\n    }\n}\n```\n\n## Herramientas complementarias\n\n### Tenderly\nPlataforma web para simular y depurar transacciones con visualización del stack:\n```\nhttps:\u002F\u002Fdashboard.tenderly.co\u002Ftx\u002Fmainnet\u002F0xABC...\n```\n\n### evm.codes\nReferencia interactiva de opcodes con playground para probar bytecode:\n```\nhttps:\u002F\u002Fwww.evm.codes\u002Fplayground\n```\n\n### Bytecode descompiladores\nHerramientas como Heimdall pueden descompilar bytecode a pseudo-Solidity, ayudando a entender contratos de terceros.\n\n## Técnicas de depuración para Huff\n\n### Logging temporal con eventos\nDurante el desarrollo, inserta eventos para trazar valores:\n\n```huff\n#define macro DEBUG_LOG_UINT() = takes(1) returns(1) {\n    \u002F\u002F Stack: [value]\n    dup1                    \u002F\u002F [value, value]\n    0x00 mstore             \u002F\u002F [value]\n    0x00                    \u002F\u002F topic0 = 0 (debug event)\n    0x20 0x00 log1          \u002F\u002F [value]\n}\n```\n\n### Verificación de invariantes en runtime\n```huff\n#define macro ASSERT_EQ() = takes(2) returns(0) {\n    \u002F\u002F Stack: [a, b]\n    eq assert jumpi\n    0x00 0x00 revert\n    assert:\n}\n```\n\n## Patrones comunes de bugs en Huff\n\n1. **Stack underflow** — POP de stack vacío. Causa: macro con takes() incorrecto\n2. **Off-by-one en DUP\u002FSWAP** — DUP2 en vez de DUP3. Causa: contar mal la profundidad del stack\n3. **Calldata offset erróneo** — Leer del offset equivocado. Causa: no contar el selector de 4 bytes\n4. **Memory overlap** — Escribir sobre datos necesarios. Causa: no gestionar el free memory pointer\n5. **Storage slot collision** — Dos variables mapeadas al mismo slot. Causa: hash incorrecto del mapping\n\n## Conclusión\n\nLa depuración de bytecode EVM es un arte que requiere paciencia y herramientas adecuadas. Foundry, cast run, y el debugger interactivo son el toolkit esencial. Para contratos Huff, los comentarios de stack diligentes y el testing diferencial contra implementaciones de referencia son la primera línea de defensa contra bugs silenciosos.","\u003Ch2 id=\"el-reto-de-depurar-bytecode\">El reto de depurar bytecode\u003C\u002Fh2>\n\u003Cp>Cuando un contrato Huff o Yul falla, no hay mensajes de error legibles — solo un REVERT silencioso. La depuración de bytecode requiere herramientas especializadas que muestren el estado del stack, memoria y storage en cada paso.\u003C\u002Fp>\n\u003Ch2 id=\"trazas-de-ejecuci-n-con-foundry\">Trazas de ejecución con Foundry\u003C\u002Fh2>\n\u003Cp>Foundry proporciona trazas detalladas con el flag \u003Ccode>-vvvv\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">forge test --match-test testTransfer -vvvv\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>La salida muestra:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>[PASS] testTransfer()\n  Traces:\n    [65432] HuffToken::transfer(alice, 100)\n      PUSH1 0x00\n      CALLDATALOAD\n      PUSH1 0xe0\n      SHR\n      ...\n      SSTORE [slot: 0x..., value: 900]\n      SSTORE [slot: 0x..., value: 100]\n      LOG3 (Transfer event)\n      RETURN\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"cast-run-an-lisis-de-transacciones-on-chain\">cast run: análisis de transacciones on-chain\u003C\u002Fh2>\n\u003Cp>\u003Ccode>cast run\u003C\u002Fcode> de Foundry reproduce una transacción con traza completa:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\"># Reproducir una transacción fallida\ncast run 0xABC123...DEF --rpc-url https:\u002F\u002Feth.llamarpc.com -vvvv\n\n# Con traza de opcodes\ncast run 0xABC123...DEF --debug\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Esto es invaluable para entender por qué una transacción de un bot MEV falló en producción.\u003C\u002Fp>\n\u003Ch2 id=\"depuraci-n-paso-a-paso\">Depuración paso a paso\u003C\u002Fh2>\n\u003Cp>Foundry incluye un debugger interactivo:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">forge debug --debug src\u002Ftest\u002FMiTest.t.sol --sig \"testTransfer()\"\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>El debugger muestra:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Estado del stack en cada opcode\u003C\u002Fli>\n\u003Cli>Contenido de la memoria\u003C\u002Fli>\n\u003Cli>Slots de storage modificados\u003C\u002Fli>\n\u003Cli>Gas restante\u003C\u002Fli>\n\u003Cli>Programa counter y opcode actual\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"an-lisis-de-reverts\">Análisis de reverts\u003C\u002Fh2>\n\u003Cp>Cuando un contrato revierte, el proceso de diagnóstico es:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Identificar el opcode REVERT\u003C\u002Fstrong> — ¿En qué posición del bytecode ocurre?\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Trazar hacia atrás\u003C\u002Fstrong> — ¿Qué condición falló justo antes del REVERT?\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Inspeccionar el stack\u003C\u002Fstrong> — ¿Los valores son los esperados?\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Verificar calldata\u003C\u002Fstrong> — ¿Se decodificaron correctamente los parámetros?\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F En tu test, captura el error:\nfunction testShouldRevert() public {\n    (bool ok, bytes memory returnData) = token.call(\n        abi.encodeWithSignature(\"transfer(address,uint256)\", address(0), 100)\n    );\n    \n    assertFalse(ok, \"Debe revertir para address(0)\");\n    \n    \u002F\u002F Decodificar datos de revert si los hay\n    if (returnData.length &gt;= 4) {\n        bytes4 selector = bytes4(returnData);\n        emit log_named_bytes4(\"Error selector\", selector);\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"herramientas-complementarias\">Herramientas complementarias\u003C\u002Fh2>\n\u003Ch3>Tenderly\u003C\u002Fh3>\n\u003Cp>Plataforma web para simular y depurar transacciones con visualización del stack:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>https:\u002F\u002Fdashboard.tenderly.co\u002Ftx\u002Fmainnet\u002F0xABC...\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>evm.codes\u003C\u002Fh3>\n\u003Cp>Referencia interactiva de opcodes con playground para probar bytecode:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>https:\u002F\u002Fwww.evm.codes\u002Fplayground\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Bytecode descompiladores\u003C\u002Fh3>\n\u003Cp>Herramientas como Heimdall pueden descompilar bytecode a pseudo-Solidity, ayudando a entender contratos de terceros.\u003C\u002Fp>\n\u003Ch2 id=\"t-cnicas-de-depuraci-n-para-huff\">Técnicas de depuración para Huff\u003C\u002Fh2>\n\u003Ch3>Logging temporal con eventos\u003C\u002Fh3>\n\u003Cp>Durante el desarrollo, inserta eventos para trazar valores:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro DEBUG_LOG_UINT() = takes(1) returns(1) {\n    \u002F\u002F Stack: [value]\n    dup1                    \u002F\u002F [value, value]\n    0x00 mstore             \u002F\u002F [value]\n    0x00                    \u002F\u002F topic0 = 0 (debug event)\n    0x20 0x00 log1          \u002F\u002F [value]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Verificación de invariantes en runtime\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro ASSERT_EQ() = takes(2) returns(0) {\n    \u002F\u002F Stack: [a, b]\n    eq assert jumpi\n    0x00 0x00 revert\n    assert:\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"patrones-comunes-de-bugs-en-huff\">Patrones comunes de bugs en Huff\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\u003Cstrong>Stack underflow\u003C\u002Fstrong> — POP de stack vacío. Causa: macro con takes() incorrecto\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Off-by-one en DUP\u002FSWAP\u003C\u002Fstrong> — DUP2 en vez de DUP3. Causa: contar mal la profundidad del stack\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Calldata offset erróneo\u003C\u002Fstrong> — Leer del offset equivocado. Causa: no contar el selector de 4 bytes\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Memory overlap\u003C\u002Fstrong> — Escribir sobre datos necesarios. Causa: no gestionar el free memory pointer\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Storage slot collision\u003C\u002Fstrong> — Dos variables mapeadas al mismo slot. Causa: hash incorrecto del mapping\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"conclusi-n\">Conclusión\u003C\u002Fh2>\n\u003Cp>La depuración de bytecode EVM es un arte que requiere paciencia y herramientas adecuadas. Foundry, cast run, y el debugger interactivo son el toolkit esencial. Para contratos Huff, los comentarios de stack diligentes y el testing diferencial contra implementaciones de referencia son la primera línea de defensa contra bugs silenciosos.\u003C\u002Fp>\n","es","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:31.607069Z","Depuración de Bytecode EVM — Trazas, Volcados de Stack y cast run","Técnicas de depuración para bytecode EVM: trazas con Foundry, cast run, debugger interactivo y patrones comunes de bugs en Huff.","depuración bytecode EVM",null,"index, follow",[],"Blockchain",[24,30,36],{"id":25,"title":26,"slug":27,"excerpt":28,"locale":12,"category_name":22,"published_at":29},"d0000000-0000-0000-0000-000000000614","La capa de interoperabilidad de Ethereum: Como 55+ L2s se convierten en una sola cadena","capa-interoperabilidad-ethereum-55-l2s-una-sola-cadena","Ethereum tiene 55+ rollups Layer 2, fragmentando la liquidez y la experiencia del usuario. La capa de interoperabilidad de Ethereum — combinando mensajeria cross-rollup, secuenciadores compartidos y based rollups — busca unificarlos en una red componible unica.","2026-03-28T10:44:45.451917Z",{"id":31,"title":32,"slug":33,"excerpt":34,"locale":12,"category_name":22,"published_at":35},"d0000000-0000-0000-0000-000000000613","Pruebas ZK mas alla de los rollups: Inferencia de IA verificable en Ethereum","pruebas-zk-mas-alla-rollups-inferencia-ia-verificable-ethereum","Las pruebas de conocimiento cero ya no son solo una herramienta de escalabilidad. En 2026, zkML permite la inferencia de IA verificable on-chain, los coprocesadores ZK mueven el calculo pesado off-chain con verificacion on-chain, y nuevos sistemas de prueba como SP1 y Jolt lo hacen practico.","2026-03-28T10:44:45.446211Z",{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":22,"published_at":41},"d0000000-0000-0000-0000-000000000590","EIP-7702 en la practica: construir flujos de cuenta inteligente despues de Pectra","eip-7702-en-la-practica-construir-flujos-cuenta-inteligente-despues-pectra","EIP-7702 permite a cualquier EOA de Ethereum actuar temporalmente como contrato inteligente en una sola transaccion. Asi se implementan transacciones por lotes, patrocinio de gas y recuperacion social con la nueva primitiva de account abstraction.","2026-03-28T10:44:43.986612Z",{"id":13,"name":43,"slug":44,"bio":45,"photo_url":19,"linkedin":19,"role":46,"created_at":47,"updated_at":47},"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"]