🧰 UtlKit

ABI-Encoder So Benutzen: 4-Byte-Selektor aus keccak256, 32-Byte-Wörter, Offsets und Typblinder Decode im Browser

keccak256 über die kanonische Signatur liefert den 4-Byte-Selektor, jeder statische Wert wird zu einem 32-Byte-Wort mit Nullen, dynamische Werte tragen einen Offset ab dem ersten Head-Wort gemessen, und der typblinde Decode-Tab liest die rohen Wörter zurück, alles im Browser mit js-sha3 und BigInt berechnet.

Der ABI-Encoder wandelt eine Solidity-Funktions-Signatur und eine Liste von Parameterwerten in die Calldata-Zeichenkette mit 0x-Präfix um, die Sie in eine Transaktion kopieren würden, und das passiert komplett im Browser. Es gibt kein Backend: Die Seite bringt js-sha3 für keccak256 mit, nutzt natives BigInt für die 32-Byte-Wörter und den eingebauten UTF-8-Encoder des Browsers zum Messen von Strings. Zwei Tabs decken den Ablauf ab: Encoder nimmt Signatur und Werte und liefert den Selektor plus ein 32-Byte-Wort pro Wert, und Decoder nimmt rohes Calldata und gibt aus, was es kann. Eine Live-Vorschau des Selektors aktualisiert sich unter dem Signaturfeld, während Sie tippen, und ein Zähler meldet die Anzahl der Hex-Zeichen des Ergebnisses, damit Sie die Größe vor dem Kopieren sehen. Starten Sie bei dem ABI-Encoder-Tool und geben Sie eine Signatur in der kanonischen Form ein, zum Beispiel transfer(address,uint256).

Wie der 4-Byte-Selektor berechnet wird

Der Selektor sind die ersten 4 Bytes des keccak256-Hashes der Signatur-Zeichenkette exakt so, wie Sie sie eingegeben haben. keccak256 ist ein 256-Bit-Hash, also berechnet das Tool die komplette 64-Hex-Zeichen-Digest und behält die ersten 8 Hex-Zeichen, nämlich das 4-Byte-Präfix, das EIP-196 für die Methoden-Dispatch von Verträgen definiert. Deshalb zählt das Format: transfer(address,uint256) ergibt das wohlbekannte 0xa9059cbb, aber dieselbe Signatur mit einem Leerzeichen nach dem Komma ergibt eine völlig andere Digest und ein anderes Präfix, sodass der Aufruf die falsche Funktion adressiert oder ein Revert auslöst. Die Vorschau unter dem Signaturfeld berechnet den Selektor bei jeder Tastenbetätigung neu, also ist ein Tippfehler sofort sichtbar. Wenn Sie die komplette Digest sehen wollen, zeigt das Keccak-Hash-Tool für dieselbe Eingabe die komplette 64-Hex-Ausgabe, die ersten 4 Bytes als Funktions-Selektor und die ersten 20 Bytes in Adressform.

Wie statische Werte zu 32-Byte-Wörtern werden

Jeder statische Parameter wird als ein 32-Byte-Wort geschrieben, rechtsbündig mit Nullen aufgefüllt. Eine Adresse muss exakt 40 Hex-Zeichen sein, mit oder ohne 0x-Präfix, und wird auf 64 aufgefüllt. Ein Boolean akzeptiert true, false, 1 oder 0. Ein bytes32 akzeptiert 1 bis 64 Hex-Zeichen. Die Ganzzahlen decken die unsignierte Familie vom 8-Bit-Typ bis uint256 ab und ihre signierten 128-Bit- und 256-Bit-Pendants, und jeder Wert wird vor dem Kodieren rangegeprüft: ein int128 muss zwischen dem negativen 2^127 und 2^127 minus 1 liegen, und ein int256 zwischen dem negativen 2^255 und 2^255 minus 1. Eingaben außerhalb des Bereichs werden abgelehnt statt still gewrapped zu werden. Negative Ganzzahlen werden in Komplementärform gespeichert, also Wert plus 2^bits: stake(int256) mit -1 wird zu Selektor 0x77b71df0 plus ein Wort aus 64 f-Zeichen kodiert, genau das, was ein signiertes -1 in 32 Bytes aussieht.

Wie dynamische Werte ihren Offset erhalten

Die Parameter string, bytes und array sind dynamisch, also hält ihr Head-Slot einen Offset statt der Daten. Der Offset wird in Bytes ab dem ersten Head-Wort gemessen, dem 32-Byte-Wort direkt hinter dem 4-Byte-Selektor, nicht ab dem Selektor selbst. Bei einem einzigen dynamischen Argument beginnen die Daten im ersten Tail-Wort, das 32 Bytes hinter dem Head-Anfang liegt, also ist das Offset-Wort einfach 32. Der Tail trägt danach ein Längenwort und die eigentlichen Daten, aufgefüllt auf ein Vielfaches von 32 Bytes. Die Länge zählt UTF-8-Bytes, keine Zeichen, also verbraucht ein Emoji 4 Bytes im Zähler. greet(string) mit dem Wert hi ergibt Selektor 0xead710c4, ein Offset-Wort von 32, ein Längenwort von 2 und ein Datenwort, das mit 0x6869 beginnt, nämlich h und i in Hex, aufgefüllt mit Nullen.

Ein komplettes Encoding, Wort für Wort

Setzen Sie es mit transfer(address,uint256) zusammen, Empfänger 0x1234567890123456789012345678901234567890, Betrag 100. Das Ergebnis ist 0xa9059cbb00000000000000000000000012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000000064, und der Zähler zeigt 136 Hex-Zeichen, das sind exakt 8 für den Selektor plus 64 für das Adresswort plus 64 für das Betragswort. Der Betrag 100 steht rechtsbündig im letzten Wort, wobei 100 in Hex 64 ist, und die 48 Hex-Zeichen der Adresse sitzen am Ende ihres Worts mit 24 Nullen davor.

Was der Decode-Tab kann und was nicht

Der Decode-Tab streicht das 0x-Präfix, nimmt die ersten 8 Hex-Zeichen als Selektor und liest jedes weitere 64-Hex-Zeichen-Chunk als unsignierte 256-Bit-Ganzzahl in Dezimaldarstellung. Geben Sie ihm das Calldata von stake(uint256,uint256), meldet er Selektor 0x7b0472f0 mit zwei Parametern, 100 und 2026, die sauber hin und zurück gehen. Der Decoder ist typblind: Er hat keine ABI und keine Typliste, also kommt ein transfer-Calldata mit dem Empfänger als 48-stellige Dezimalzahl 103929005307130220006098923584552504982110632080 zurück, statt als Adresse, und ein string-Parameter kommt als rohe Offset-, Längen- und Datenwörter statt als Text. Wenn Sie die Bytes hinter einem Wort brauchen, fügen Sie den Hex-Teil in den Hex-Konverter ein, um ihn wieder als UTF-8-Text zu lesen.

Was dieses Tool nicht ist

Der ABI-Encoder ist kein typisierter Vertrags-Explorer: Er kodiert und dekodiert rohe Wörter, und wenn Sie eine Transaktion, Adresse oder einen Token on-chain nachschlagen wollen, verlinkt das Block-Explorer-Tool direkt auf Etherscan, BscScan, PolygonScan und die großen L2-Explorer. Es ist auch kein Adressprüfer: Das Empfängerwort ist 32 Bytes groß, und die Adresse sind die letzten 40 Hex-Zeichen dieses Worts, während das ETH-Adress-Check-Tool die Adresse in EIP-55-Mischschreibweise umformt und eine Checksummen-Abweichung markiert. Es ist auch keine Gebührenrechnung: Die Calldata-Länge ändert den Gasverbrauch, und der Gas-Gebühren-Schätzer rechnet eine Gas-Limit plus Base- und Priority-Fee in einen Kostenwert in ETH und USD um. Es ist auch kein Basis-Konverter für Werte: Für kleine Zahlen bestätigt der Zahlenbasis-Konverter die Umrechnung von Dezimal nach Hex, etwa 100 wird 64, aber er behandelt nur 32-Bit-Bereiche. Und es ist kein bytegenaues Text-Tool: Das Längenwort zählt UTF-8-Bytes, und wenn Sie sehen wollen, wie eine Textzeichenkette Zeichen für Zeichen aufgeht, erklärt der Text-zu-Binär-Guide die 8-Bit-Auflösung für ASCII-Eingaben.

Zugehörige Tools

Häufige Fragen

Spricht der ABI-Encoder mit einer API oder einem Server?

Nein. Die Seite bringt js-sha3 mit und führt keccak256 lokal aus, baut jedes 32-Byte-Wort mit BigInt und misst Strings mit dem in den Browser eingebauten UTF-8-Encoder. Kein einziger eingegebener Wert verlässt die Seite, abgesehen vom optionalen Feedback-Formular.

Warum ändert ein einzelnes Leerzeichen den Selektor?

keccak256 läuft über die Signatur-Zeichenkette exakt so eingegeben. Die kanonische Form hat nach dem Komma keine Leerzeichen, und genau diese Byte-Sequenz wird gehasht. Fügen Sie ein Leerzeichen ein, und Sie hashen eine andere Zeichenkette, mit anderer Digest und anderem 8-Hex-Präfix, sodass der Aufruf die falsche Funktion adressiert oder ein Revert auslöst. Die Live-Vorschau sorgt dafür, dass Sie es vor dem Kopieren bemerken.

Warum wird das dekodierte Adresswort als lange Dezimalzahl gedruckt?

Der Decoder ist typblind. Er hat keine ABI und keine Typliste, also liest er jedes 64-Hex-Zeichen-Chunk als unsignierte 256-Bit-Ganzzahl in Dezimal. Die Adresse sind die letzten 40 Hex-Zeichen ihres 32-Byte-Worts, also arbeiten Sie vom Hex aus, nicht von der gedruckten Dezimalzahl, wenn Sie den Wert an ein anderes Tool weitergeben wollen.

Warum ist der erste String-Offset 32 und nicht 4?

Offsets werden in Bytes ab dem ersten Head-Wort gemessen, dem 32-Byte-Wort direkt hinter dem 4-Byte-Selektor, nicht ab dem Selektor selbst. Bei einem einzigen dynamischen Argument beginnen die Daten im ersten Tail-Wort, das 32 Bytes hinter dem Head-Anfang liegt, also ist das Offset-Wort 32. Für greet(string) mit hi lautet das Ergebnis Selektor 0xead710c4, Offset 32, Länge 2 und ein Datenwort, das mit 0x6869 beginnt und auf 32 Bytes aufgefüllt wird.

Warum meldet der Zähler Hex-Zeichen und keine Bytes?

Jedes Byte wird zu zwei Hex-Zeichen, also stehen 136 im Zähler für 68 Bytes auf der Leitung: der 4-Byte-Selektor plus zwei 32-Byte-Wörter. Das Tool zeigt Hex-Zeichen, weil das die Form ist, die Sie kopieren, und die Wortstruktur bleibt sichtbar: Jeder zusätzliche statische Wert verlängert die Zeichenkette um 64 Zeichen, und der Selektor fügt 8 hinzu.

Verwandte Artikel