ABI-кодировщик / декодер Ethereum

Превратите сигнатуру функции с аргументами в точную calldata или вставьте calldata из транзакции и декодируйте её. Полная поддержка ABI v2: вложенные массивы, кортежи, динамические bytes и строки, с разбором по словам.

Целые числа — десятичные или 0x hex (кавычки необязательны). Адреса, bytes и строки — в кавычках. bytesN принимает 0x hex или текст.
Примеры:

Вычисляется в вашем браузере на JavaScript. Адреса никогда не загружаются на сервер и не сохраняются.

Что такое ABI-кодирование?

ABI-кодирование — это правило из спецификации ABI контрактов Solidity, по которому вызов функции превращается в байты: 4-байтный селектор, за которым следуют аргументы, упакованные в 32-байтные слова; статические значения располагаются inline, а динамические (bytes, строки, динамические массивы) — после заголовка (head), в котором хранятся их байтовые смещения. ABI-кодировщик собирает такую calldata из сигнатуры и значений; декодер делает обратное.

Как устроена раскладка

Для f(uint256,uint32[],bytes10,bytes), вызванной с (0x123, [0x456, 0x789], "1234567890", "Hello, world!"), кодирование выглядит так: селектор 0x8be65246, затем заголовок из четырёх слов (uint256, смещение 0x80 к массиву, bytes10 с дополнением справа, смещение 0xe0 к bytes), затем хвост (tail): длина массива 2 и два его элемента, потом длина bytes 13 и дополненные данные. Нажмите «f() из документации Solidity» выше, чтобы увидеть разбор по словам.

Правила вкратце

Наглядный пример: перевод ERC-20

transfer(address,uint256) с получателем 0x1111111111111111111111111111111111111111 и 25 USDT (25 000 000 сырых единиц) кодируется в 68 байт: селектор a9059cbb, затем 12 нулевых байт дополнения слева и 20-байтный адрес, затем 25 000 000 = 0x17d7840, дополненное слева до 32-байтного слова. Каждый перевод ERC-20 в любом обозревателе имеет ровно такую форму, поэтому декодер может назвать функцию и восстановить аргументы по одному лишь селектору.

См. также

Вычисляйте селекторы отдельно в инструменте селекторов функций; переводите суммы токенов в сырые целые числа в конвертере decimals токенов; разбирайте отдельные слова в конвертере hex в десятичные.

Часто задаваемые вопросы

Что такое ABI-кодирование?

Application Binary Interface определяет, как аргументы располагаются в поле data транзакции: 4-байтный селектор, за которым идут 32-байтные слова. Статические типы размещаются inline; на динамические (bytes, string, динамические массивы, кортежи с ними) ссылается смещение в заголовке, а сами они размещаются в хвосте.

Как записывать аргументы?

Как JSON-массив в порядке параметров. Целые числа могут быть обычными или 0x hex, в кавычках или без; большие значения лучше брать в кавычки или писать в hex. Адреса и строки — в кавычках. Массивы и кортежи — вложенные массивы, например [[1,2],[3]] для uint256[][].

Почему декодированное значение показано как строка?

Целые числа больше 253 нельзя точно представить числами JSON, поэтому все целые показаны как десятичные строки. Адреса показаны с контрольной суммой EIP-55.

Можно ли декодировать транзакцию из Etherscan?

Да. Скопируйте input data, вставьте вместе с сигнатурой функции — селектор сверяется с сигнатурой до декодирования. Если селектор не совпадает, вы получите ошибку, а не мусор.

В чём разница между abi.encode и abi.encodePacked?

abi.encode следует стандартным правилам выше и дополняет каждое значение до 32 байт, поэтому результат можно декодировать. abi.encodePacked склеивает значения в минимальной ширине без дополнения и смещений; он короче, но неоднозначен и не декодируется без знания типов. Этот инструмент реализует только стандартное кодирование.

Поддерживаются ли пользовательские ошибки и события?

Правила кодирования идентичны, поэтому данные ошибки можно кодировать и декодировать по сигнатуре ошибки. Логи событий устроены иначе: неиндексированные параметры ABI-кодируются в поле data, поэтому декодируйте эту часть по сигнатуре, содержащей только неиндексированные типы.