🧰 UtlKit

Cómo Usar el Codificador ABI: Selector de 4 Bytes desde keccak256, Palabras de 32 Bytes, Offsets y Decodificación Ciega en el Navegador

keccak256 sobre la firma canónica produce el selector de 4 bytes, cada valor estático se vuelve una palabra de 32 bytes rellena de ceros, los valores dinámicos llevan un offset medido desde la primera palabra de cabecera, y la pestaña de decodificación ciega lee las palabras crudas de vuelta, todo calculado en el navegador con js-sha3 y BigInt.

El Codificador ABI convierte la firma de una función Solidity y una lista de valores de parámetros en la cadena de calldata con prefijo 0x que pegarías en una transacción, y todo ocurre en el navegador. No hay backend: la página incluye js-sha3 para keccak256, usa BigInt nativo para las palabras de 32 bytes y el codificador UTF-8 del navegador para medir las cadenas. Dos pestañas cubren el flujo: codificar toma la firma y los valores y produce el selector seguido de una palabra de 32 bytes por valor, y decodificar toma calldata crudo e imprime lo que puede. Una vista previa en vivo del selector se actualiza bajo el campo de firma mientras escribes, y un contador informa el número de caracteres hex del resultado, de modo que ves el tamaño antes de copiar. Empieza con la herramienta Codificador ABI e introduce una firma en forma canónica, por ejemplo transfer(address,uint256).

Cómo se calcula el selector de 4 bytes

El selector son los primeros 4 bytes del hash keccak256 de la cadena de firma exactamente como la escribiste. keccak256 es un hash de 256 bits, así que la herramienta calcula el digesto completo de 64 caracteres hex y conserva los primeros 8 caracteres hex, que es el prefijo de 4 bytes que EIP-196 define para el despacho de métodos de contrato. Por eso importa el formato: transfer(address,uint256) hace hash al bien conocido 0xa9059cbb, pero la misma firma con un espacio después de la coma hace hash a un digesto completamente distinto y produce un prefijo distinto, de modo que la llamada apuntaría a la función equivocada o revertiría. La vista previa bajo el campo de firma recalcula el selector en cada pulsación, así que un error tipográfico se ve al instante. Si quieres ver el digesto entero, la herramienta Keccak Hash muestra la salida completa de 64 hex, los primeros 4 bytes como selector de función y los primeros 20 bytes en forma de dirección para la misma entrada.

Cómo los valores estáticos se vuelven palabras de 32 bytes

Cada parámetro estático se escribe como una palabra de 32 bytes, alineada a la derecha con relleno de ceros. Una dirección debe ser exactamente 40 caracteres hex, con o sin prefijo 0x, y se completa a 64. Un booleano acepta true, false, 1 o 0. Un bytes32 acepta de 1 a 64 caracteres hex. Los enteros cubren la familia sin signo desde el tipo de 8 bits hasta uint256 y sus primos con signo de 128 y 256 bits, y cada valor se comprueba por rango antes de codificarse: un int128 debe estar entre el negativo de 2^127 y 2^127 menos 1, y un int256 entre el negativo de 2^255 y 2^255 menos 1. La entrada fuera de rango se rechaza en vez de rodear en silencio. Un entero negativo se guarda en forma de complemento, es decir el valor más 2^bits: stake(int256) con -1 se codifica al selector 0x77b71df0 seguido de una palabra de 64 caracteres f, que es exactamente lo que un -1 con signo parece en 32 bytes.

Cómo los valores dinámicos reciben su offset

Los parámetros string, bytes y array son dinámicos, así que su slot de cabecera guarda un offset en vez de los datos. El offset se mide en bytes desde la primera palabra de cabecera, la palabra de 32 bytes que queda justo después del selector de 4 bytes, no desde el selector mismo. Con un único argumento dinámico los datos empiezan en la primera palabra de cola, que está 32 bytes más allá del inicio de cabecera, así que la palabra de offset es simplemente 32. La cola lleva después una palabra de longitud y los datos reales rellenados hasta un múltiplo de 32 bytes. La longitud cuenta bytes UTF-8, no caracteres, de modo que un emoji consume 4 bytes en el recuento. greet(string) con el valor hi produce el selector 0xead710c4, una palabra de offset de 32, una palabra de longitud de 2 y una palabra de datos que empieza por 0x6869, que es h e i en hex, rellenada con ceros.

Una codificación completa, palabra a palabra

Agrúpalo todo con transfer(address,uint256), destinatario 0x1234567890123456789012345678901234567890 y monto 100. El resultado es 0xa9059cbb00000000000000000000000012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000000064, y el contador marca 136 caracteres hex, que es exactamente 8 por el selector más 64 por la palabra de dirección más 64 por la palabra de monto. El monto 100 queda alineado a la derecha en la palabra final, donde 100 es 64 en hex, y los 48 caracteres hex de la dirección se sientan al final de su palabra con 24 ceros delante.

Lo que la pestaña de decodificación hace y no hace

La pestaña de decodificar quita el prefijo 0x, toma los primeros 8 caracteres hex como selector y lee cada trozo de 64 caracteres hex que sigue como un entero sin signo de 256 bits impreso en decimal. Si le das la calldata de stake(uint256,uint256), informa el selector 0x7b0472f0 con dos parámetros, 100 y 2026, que viaja de ida y vuelta sin problemas. El decodificador es ciego a los tipos: no tiene ABI ni lista de tipos, de modo que una calldata de transfer vuelve con el destinatario como el decimal de 48 dígitos 103929005307130220006098923584552504982110632080 en vez de una dirección, y un parámetro string vuelve como palabras crudas de offset, longitud y datos en vez de texto. Cuando necesitas los bytes detrás de una palabra, pega la porción hex en el Convertidor Hex para leerla de nuevo como texto UTF-8.

Lo que esta herramienta no es

El Codificador ABI no es un explorador de contratos con tipos: codifica y decodifica palabras crudas, y si quieres buscar una transacción, dirección o token en cadena, la herramienta Block Explorer enlaza directo a Etherscan, BscScan, PolygonScan y los exploradores principales de L2. Tampoco es un verificador de direcciones: la palabra del destinatario tiene 32 bytes y la dirección son los últimos 40 caracteres hex de esa palabra, mientras que la herramienta ETH Address Check vuelve a formatear la dirección en mayúsculas y minúsculas EIP-55 y señala un desfase de suma de verificación. No es una calculadora de comisiones: la longitud de la calldata cambia el gas, y el Estimador de Comisiones Gas convierte un límite de gas más tarifas base y de prioridad en un costo en ETH y USD. No es un convertidor de bases para valores: para números pequeños el Convertidor de Base confirma la conversión de decimal a hex, como 100 volverse 64, pero solo maneja rangos de 32 bits. Y no es una herramienta de texto a nivel de bytes: la palabra de longitud cuenta bytes UTF-8, y si quieres ver cómo se expande una cadena de texto carácter a carácter, la guía de Texto a Binario recorre la expansión de 8 bits para entradas ASCII.

Herramientas Relacionadas

Preguntas Frecuentes

¿El Codificador ABI habla con alguna API o servidor?

No. La página incluye js-sha3 y ejecuta keccak256 en local, arma cada palabra de 32 bytes con BigInt y mide las cadenas con el codificador UTF-8 integrado en el navegador. Nada de lo que escribes sale de la página, salvo el formulario opcional de comentarios.

¿Por qué un solo espacio cambia el selector?

keccak256 se calcula sobre la cadena de firma exactamente como la escribiste. La forma canónica no lleva espacios tras la coma, y es esa secuencia exacta de bytes la que se hace hash. Añade un espacio y harás hash de otra cadena, con otro digesto y otro prefijo de 8 hex, de modo que la llamada apunta a la función equivocada o revierte. La vista previa en vivo está ahí para que lo veas antes de copiar.

¿Por qué la palabra de dirección decodificada se imprime como un decimal largo?

El decodificador es ciego a los tipos. No tiene ABI ni lista de tipos, así que lee cada trozo de 64 hex como un entero sin signo de 256 bits en decimal. La dirección son los últimos 40 caracteres hex de su palabra de 32 bytes, de modo que trabajes desde el hex, no desde el decimal impreso, cuando necesites pasar el valor a otra herramienta.

¿Por qué el primer offset de string es 32 y no 4?

Los offsets se miden en bytes desde la primera palabra de cabecera, la palabra de 32 bytes justo después del selector de 4 bytes, no desde el selector mismo. Con un único argumento dinámico, los datos empiezan en la primera palabra de cola, que está 32 bytes más allá del inicio de cabecera, así que la palabra de offset es 32. Con greet(string) y hi, el resultado es el selector 0xead710c4, offset 32, longitud 2 y una palabra de datos que empieza por 0x6869 rellenada a 32 bytes.

¿Por qué el contador informa caracteres hex en vez de bytes?

Cada byte se convierte en dos caracteres hex, así que un contador que marca 136 significa 68 bytes en la red, el selector de 4 bytes más dos palabras de 32 bytes. La herramienta muestra caracteres hex porque es la forma que copias, y deja clara la estructura de palabras: cada valor estático que añades alarga la cadena 64 caracteres, y el selector añade 8.

Artículos Relacionados