🧰 UtlKit

Como Usar o Codificador ABI: Seletor de 4 Bytes do keccak256, Palavras de 32 Bytes, Offsets e Decodificação Cega no Navegador

keccak256 sobre a assinatura canônica produz o seletor de 4 bytes, cada valor estático vira uma palavra de 32 bytes com zeros, os valores dinâmicos levam um offset medido a partir da primeira palavra de cabeçalho, e a aba de decodificação cega lê as palavras cruas de volta, tudo calculado no navegador com js-sha3 e BigInt.

O Codificador ABI transforma a assinatura de uma função Solidity e uma lista de valores de parâmetros na string de calldata com prefixo 0x que você colaria em uma transação, e tudo isso acontece no navegador. Não há backend: a página traz js-sha3 para keccak256, usa BigInt nativo para as palavras de 32 bytes e o codificador UTF-8 do navegador para medir strings. Duas abas cobrem o fluxo: codificar recebe a assinatura e os valores e produz o seletor seguido de uma palavra de 32 bytes por valor, e decodificar recebe calldata bruta e imprime o que consegue. Uma pré-visualização em vivo do seletor se atualiza sob o campo de assinatura enquanto você digita, e um contador informa o número de caracteres hex do resultado, então você vê o tamanho antes de copiar. Comece por a ferramenta Codificador ABI e entre uma assinatura na forma canônica, por exemplo transfer(address,uint256).

Como o seletor de 4 bytes é calculado

O seletor são os primeiros 4 bytes do hash keccak256 da string de assinatura exatamente como você digitou. keccak256 é um hash de 256 bits, então a ferramenta calcula o dígito completo de 64 caracteres hex e mantém os primeiros 8 caracteres hex, que é o prefixo de 4 bytes que EIP-196 define para o despacho de métodos de contrato. Por isso o formato importa: transfer(address,uint256) resulta no bem conhecido 0xa9059cbb, mas a mesma assinatura com um espaço após a vírgula resulta em um dígito completamente diferente e produz um prefixo diferente, de modo que a chamada miraria a função errada ou reverteria. A pré-visualização sob o campo de assinatura recalcula o seletor a cada tecla, então um erro de digitação aparece na hora. Se você quiser ver o dígito inteiro, a ferramenta Keccak Hash mostra a saída completa de 64 hex, os primeiros 4 bytes como seletor de função e os primeiros 20 bytes em forma de endereço para a mesma entrada.

Como os valores estáticos viram palavras de 32 bytes

Cada parâmetro estático é escrito como uma palavra de 32 bytes, alinhada à direita com zeros à esquerda. Um endereço deve ter exatamente 40 caracteres hex, com ou sem prefixo 0x, e é completado até 64. Um booleano aceita true, false, 1 ou 0. Um bytes32 aceita de 1 a 64 caracteres hex. Os inteiros cobrem a família sem sinal desde o tipo de 8 bits até uint256 e seus primos com sinal de 128 e 256 bits, e cada valor é verificado por intervalo antes de ser codificado: um int128 deve ficar entre o negativo de 2^127 e 2^127 menos 1, e um int256 entre o negativo de 2^255 e 2^255 menos 1. Entrada fora do intervalo é rejeitada em vez de fazer wrap em silêncio. Um inteiro negativo é armazenado em forma de complemento, ou seja o valor mais 2^bits: stake(int256) com -1 é codificado para o seletor 0x77b71df0 seguido de uma palavra de 64 caracteres f, que é exatamente como um -1 com sinal aparece em 32 bytes.

Como os valores dinâmicos recebem o offset

Parâmetros string, bytes e array são dinâmicos, então seu slot de cabeçalho guarda um offset em vez dos dados. O offset é medido em bytes a partir da primeira palavra de cabeçalho, a palavra de 32 bytes que fica logo após o seletor de 4 bytes, não a partir do próprio seletor. Com um único argumento dinâmico, os dados começam na primeira palavra de cauda, que está 32 bytes à frente do início do cabeçalho, então a palavra de offset é simplesmente 32. A cauda traz depois uma palavra de comprimento e os dados reais completados até um múltiplo de 32 bytes. O comprimento conta bytes UTF-8, não caracteres, então um emoji consome 4 bytes na contagem. greet(string) com o valor hi produz o seletor 0xead710c4, uma palavra de offset de 32, uma palavra de comprimento de 2 e uma palavra de dados que começa com 0x6869, que é h e i em hex, completada com zeros.

Uma codificação completa, palavra por palavra

Junte tudo com transfer(address,uint256), destinatário 0x1234567890123456789012345678901234567890 e valor 100. O resultado é 0xa9059cbb00000000000000000000000012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000000064, e o contador marca 136 caracteres hex, que é exatamente 8 pelo seletor mais 64 pela palavra de endereço mais 64 pela palavra de valor. O valor 100 fica à direita na palavra final, onde 100 é 64 em hex, e os 48 caracteres hex do endereço ficam no fim da sua palavra com 24 zeros à frente.

O que a aba de decodificação faz e não faz

A aba de decodificar remove o prefixo 0x, toma os primeiros 8 caracteres hex como seletor e lê cada pedaço de 64 caracteres hex seguinte como um inteiro sem sinal de 256 bits impresso em decimal. Se você alimenta a calldata de stake(uint256,uint256), ela reporta o seletor 0x7b0472f0 com dois parâmetros, 100 e 2026, que vai e volta sem problema. O decodificador é cego a tipos: não tem ABI nem lista de tipos, então uma calldata de transfer volta com o destinatário como o decimal de 48 dígitos 103929005307130220006098923584552504982110632080 em vez de um endereço, e um parâmetro string volta como palavras cruas de offset, comprimento e dados em vez de texto. Quando você precisa dos bytes por trás de uma palavra, cole a parte hex no Conversor Hex para lê-la de volta como texto UTF-8.

O que esta ferramenta não é

O Codificador ABI não é um explorador de contratos com tipos: ele codifica e decodifica palavras cruas, e se você quer procurar uma transação, endereço ou token on-chain, a ferramenta Block Explorer leva direto para Etherscan, BscScan, PolygonScan e os principais exploradores de L2. Também não é um verificador de endereços: a palavra do destinatário tem 32 bytes e o endereço são os últimos 40 caracteres hex daquela palavra, enquanto a ferramenta ETH Address Check reformata o endereço em caixa mista EIP-55 e sinaliza um descompasso de soma de verificação. Não é uma calculadora de taxas: o comprimento da calldata muda o uso de gas, e o Estimador de Taxa Gas transforma um limite de gas mais taxas base e de prioridade em custo em ETH e USD. Não é um conversor de bases para valores: para números pequenos o Conversor de Base confirma a conversão de decimal para hex, como 100 virar 64, mas só lida com faixas de 32 bits. E não é uma ferramenta de texto em nível de byte: a palavra de comprimento conta bytes UTF-8, e se você quer ver como uma string de texto se expande caractere por caractere, o guia de Texto para Binário percorre a expansão de 8 bits para entradas ASCII.

Ferramentas Relacionadas

Perguntas Frequentes

O Codificador ABI fala com alguma API ou servidor?

Não. A página traz js-sha3 e executa keccak256 em local, monta cada palavra de 32 bytes com BigInt e mede as strings com o codificador UTF-8 embutido no navegador. Nada do que você digita sai da página, exceto o formulário opcional de comentários.

Por que um único espaço muda o seletor?

keccak256 roda sobre a string de assinatura exatamente como digitada. A forma canônica não tem espaço após a vírgula, e é essa sequência exata de bytes que é hasheada. Acrescente um espaço e você faz o hash de outra string, com outro resumo e outro prefixo de 8 hex, então a chamada mira a função errada ou reverte. A pré-visualização em vivo serve para você ver isso antes de copiar.

Por que a palavra de endereço decodificada imprime como um decimal longo?

O decodificador é cego a tipos. Não tem ABI nem lista de tipos, então lê cada pedaço de 64 hex como um inteiro sem sinal de 256 bits em decimal. O endereço são os últimos 40 caracteres hex da sua palavra de 32 bytes, então trabalhe a partir do hex, não do decimal impresso, quando precisar passar o valor para outra ferramenta.

Por que o primeiro offset de string é 32 e não 4?

Os offsets são medidos em bytes a partir da primeira palavra de cabeçalho, a palavra de 32 bytes logo após o seletor de 4 bytes, não a partir do próprio seletor. Com um único argumento dinâmico, os dados começam na primeira palavra de cauda, que está 32 bytes à frente do início do cabeçalho, então a palavra de offset é 32. Para greet(string) com hi, o resultado é o seletor 0xead710c4, offset 32, comprimento 2 e uma palavra de dados começando com 0x6869 completada a 32 bytes.

Por que o contador informa caracteres hex em vez de bytes?

Cada byte vira dois caracteres hex, então um contador marcando 136 significa 68 bytes no ar, o seletor de 4 bytes mais duas palavras de 32 bytes. A ferramenta mostra caracteres hex porque é a forma que você copia, e deixa clara a estrutura de palavras: cada valor estático que você adiciona alonga a string em 64 caracteres, e o seletor soma 8.

Artigos Relacionados