Solo con fines educativos; no constituye asesoramiento de inversión. Invertir puede ocasionar pérdidas.
Respuesta directa
Calldata es la cadena inmutable de bytes suministrada como entrada a una transacción de nivel superior de Ethereum o a una llamada interna. Una llamada convencional a una función Solidity comienza con un selector de 4-byte seguido de argumentos codificados con ABI, pero calldata no se describe a sí misma: los mismos bytes pueden significar cosas distintas para diferentes códigos en ejecución, implementaciones de proxy o esquemas. Las funciones fallback, el ensamblador sin procesar y los protocolos ajenos a Solidity no tienen por qué seguir la ABI convencional de funciones.
Por tanto, una wallet debe mostrar algo más que un posible nombre de función. Una revisión segura vincula los bytes con chainId, un bloque, from, to, el value nativo, el codeHash en ejecución, la implementación activa y una ABI fiable; decodifica estrictamente cada llamada anidada; distingue calldata on-chain de firmas EIP-712; simula en un estado explícito; y concilia el recibo y los cambios de estado reales después de la inclusión.
Completar esta revisión no demuestra que un activo, una transacción o un sistema sean seguros.
Cómo funciona
- Fija el sobre de firma y el punto de observación:
chainId, número y hash del bloque,from,to,valuenativo, bytes de entrada, nonce y campos de comisiones. Conserva la fuente de wallet o RPC; una carga decodificada en otra red o bloque no representa la misma afirmación. - Clasifica el objeto antes de decodificar. Una transacción, una solicitud de datos tipados EIP-712, un permit ERC-2612, una UserOperation ERC-4337 y un mensaje personal-sign sin procesar usan dominios y esquemas distintos; no los fuerces a todos por la ABI de transacciones.
- Resuelve el destino en el bloque fijado. Lee el bytecode en ejecución y el
codeHash; identifica proxy, beacon o implementación cuando proceda; registra los slots de implementación y administración; y obtiene una ABI correspondiente a esa versión exacta del código. Un registro de selectores ofrece candidatos, no autoridad. - Decodifica estrictamente. El selector son los primeros
4 bytesde Keccak-256 de la firma canónica de la función, sin tipos de retorno. Los valores estáticos ocupan palabras de32-byte; las cabeceras dinámicas contienen offsets desde el bloque de argumentos posterior al selector. Rechaza datos truncados, offsets fuera de límites, longitudes imposibles, padding inválido y bytes finales sin explicar. - Expande recursivamente multicalls, calldata anidada y ejecución delegada. Para cada llamada hija, enumera destino, valor nativo, selector, argumentos, tipo de llamada y cualquier indicador
allowFailure. Condelegatecall, el código de implementación se ejecuta en el contexto de dirección, saldo y almacenamiento del llamador, conservandomsg.senderymsg.value. - Construye registros separados de autoridad y valor, y después simula. Registra destinatarios, spenders, operadores NFT, unidades brutas de tokens, decimales, plazos, límites de slippage y valor nativo. Simula con bloque, remitente y valor exactos, pero trata el resultado como instantánea condicional: estado, precios, tiempo, código y orden de transacciones pueden cambiar.
- Confirma cada campo material antes de firmar. Tras la inclusión, inspecciona estado del recibo, logs, trazas disponibles y variaciones de saldos, allowances y operadores; distingue fallos hijos capturados del éxito de nivel superior; contabiliza gas incluso en un revert; espera la finalidad requerida; y detente en vez de volver a firmar a ciegas un fallo inexplicado.
Ejemplos desarrollados
- Transferencia ERC-20 estática.
transfer(address,uint256)suele usar el selector0xa9059cbb. Un selector y dos palabras ABI suman4 + 2 * 32 = 68 bytes. Un importe bruto de1,500,000para un token cuyo uso de6 decimalsse ha verificado independientemente se muestra como1.5 tokens. Los decimales son metadatos externos del contrato, no están codificados en esos argumentos, y el selector por sí solo no identifica de manera única el contrato ni la función. - Offset de bytes dinámicos. Para
f(address,bytes)con una carga de3-byte, la cabecera de dos palabras ocupa64 bytes. El offset dinámico es0x40, medido desde el inicio del bloque de argumentos y sin incluir el selector. Su cola contiene una palabra de longitud de32-bytey una palabra de datos con padding de32-byte, de modo que la calldata total es4 + 64 + 32 + 32 = 132 bytes. Tratar el offset como absoluto desde el byte cero desplaza el destino cuatro bytes. - El valor de un lote depende de la implementación. Una llamada externa lleva
1.00 ETH; tres llamadas hijas decodificadas solicitan expresamente0.20 ETH,0.30 ETHy0.10 ETH, que suman0.60 ETH. Los0.40 ETHrestantes podrían reembolsarse, retenerse, reenviarse o provocar un revert según el código del lote. Si la tercera llamada falla conallowFailure=true, las anteriores pueden quedar confirmadas; una implementación atómica puede revertirlo todo. - Un permit no es la calldata del relayer al firmarlo. Un propietario con
1,000 USDCfirma un permit ERC-2612 por300 USDCen el nonce41. La firma por sí sola no modifica saldo ni allowance. Cuando un relayer lo envía con éxito, el nonce pasa a42y la allowance a300; después de que el spender use180, el saldo es820y la allowance restante120. Desconectar el sitio no revoca el permiso.
Riesgos
- Decodificar con una red, fork, etiqueta de bloque o sobre de transacción equivocados.
- Firmar para un dominio, dirección de destino o destinatario suplantados.
- Tratar un selector de
4-bytecomo único pese a posibles colisiones. - Usar una ABI supuesta, obsoleta o verificada incorrectamente.
- Confiar en una etiqueta de fuente verificada sin compararla con el
codeHashactual. - No detectar una actualización de implementación, beacon o administrador entre revisión y ejecución.
- Ignorar una función proxy cuyo selector colisiona con el de la implementación.
- Olvidar que
delegatecallescribe en el contexto de almacenamiento del llamador. - Aceptar offsets, longitudes, padding o bytes finales dinámicos malformados.
- No expandir un lote anidado que oculta destinos, valores o permisos.
- Suponer atomicidad cuando la implementación captura o permite fallos hijos.
- Ignorar el
valuenativo de nivel superior porque los argumentos de tokens parecen inocuos. - Aplicar decimales erróneos o suponer que tokens con comisión de transferencia o rebasing son ERC-20 estándar.
- Conceder una allowance ERC-20 ilimitada o gestionar mal la carrera al actualizarla.
- Pasar por alto el alcance sobre toda la colección de
setApprovalForAllpara NFT. - Confundir datos tipados EIP-712 o un permit ERC-2612 con calldata de transacción.
- Omitir nonce, plazo, contrato verificador, dominio de red o límites de replay.
- Tratar la simulación como estable pese a cambios de oráculo, timestamp, estado pendiente, MEV o código.
- Tratar el estado del recibo, logs o trazas del proveedor como prueba completa del estado económico.
- Volver a firmar a ciegas mediante una UI comprometida o ignorar riesgos de inclusión, reorganización y finalidad.
Errores comunes
- Un selector de función identifica de manera única qué ejecutará el contrato.
- Un resumen verificado del frontend es idéntico a los bytes y la implementación actual que se firman.
- Una transacción con
value=0no puede mover tokens, NFT ni activos delegados. - Una simulación o un recibo correctos demuestran seguridad y el resultado económico previsto.
- Desconectar una dapp revoca aprobaciones, permits y permisos de operadores NFT.
Temas relacionados
Fuentes
- Contract ABI Specification - Solidity Documentation (consultado: 2026-08-12)
- Introduction to Smart Contracts - Solidity Documentation (consultado: 2026-08-12)
- Transactions - Ethereum.org (consultado: 2026-08-12)
- ERC-20: Token Standard - Ethereum Improvement Proposals (consultado: 2026-08-12)
- EIP-712: Typed structured data hashing and signing - Ethereum Improvement Proposals (consultado: 2026-08-12)
- ERC-2612: Permit Extension for EIP-20 Signed Approvals - Ethereum Improvement Proposals (consultado: 2026-08-12)
- ERC-721: Non-Fungible Token Standard - Ethereum Improvement Proposals (consultado: 2026-08-12)
- ERC-1967: Proxy Storage Slots - Ethereum Improvement Proposals (consultado: 2026-08-12)