Как кодировать и декодировать данные ABI?
Может ли кто-нибудь показать мне пример с библиотекой web3js?
Если вопрос касается параметров abi, вы можете взглянуть на эти два файла web3.js:
https://github.com/ChainSafe/web3.js/blob/0.20.7/test/coder.encodeParam.js https://github.com/ChainSafe/web3.js/blob/0.20.7/test/coder .decodeParam.js
Хотя эти функции не являются частью публичного web3.js
интерфейса. В основном потому, что им нужен правильный рефакторинг.
Существует также инструмент командной строки, созданный специально для кодирования вызовов функций и извлечения выходных данных.
Если вам нужен онлайн-инструмент для кодирования параметров в формат abi, вы можете использовать https://abi.hashex.org/ . Он имеет функциональные возможности для автоматического анализа abi контракта для получения имен функций и типов параметров и предоставляет удобный способ ввода их значений.
веб3 1.0:
web3.eth.abi.decodeParameter('address', '0000000000000000000000001829d79cce6aa43d13e67216b355e81a7fffb220')
вы должны получить:0x1829D79cCE6aA43D13E67216b355E81A7FfFB220
Вы также можете попробовать:
Я изменил библиотеку web3 npm, включив следующую строку
Web3.SolidityCoder = require('./lib/solidity/coder');
после создания объекта Web3.
На стороне клиента вы можете использовать его со следующим кодом.
web3 = require('web3'); // This will import the web3 library.
web3.SolidityCoder.encodeParams([types array], [values array])
web3.SolidityCoder.decodeParams([types array], encodedData)
Это, конечно, хак и подходит для быстрого тестирования, если бы это был рекомендуемый подход, я мог бы внести изменения в официальную библиотеку web3. Я проверю у них.
Обновление: в web3.js доступен метод getData(), который вы можете использовать для этой цели. Вот ссылка на документацию: https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-methods
Самый простой способ — использовать « аби-декодер ». Я разветвил репозиторий и создал index.html для удобства использования.
Вы можете загрузить и использовать его с: https://github.com/Muhammad-Altabba/abi-decoder (позже вы можете проверить его на https://github.com/ConsenSys/abi-decoder , как только они примут мой запрос на включение )
Чтобы загрузить и запустить с помощью NPM:
npm install abi-decoder
bower install abi-decoder
Затем загрузите https://github.com/Muhammad-Altabba/abi-decoder/index.html в тот же каталог. Затем откройте файл «index.html» в браузере.
Ты получишь:
Если вы имеете в виду данные для отправки сообщения, простой способ — закодировать их так:
contract = web3.eth.contract(abi).at(cAddr);
payload = contract['transfer'].getData(to, amont);
Это payload
именно то, что вы хотите.
Документация по языку солидности имеет формальное объяснение: https://docs.soliditylang.org/en/v0.4.24/abi-spec.html#argument-encoding
TL;DR заключается в том, что первые 4 байта являются сигнатурой функции. Аргументы разбиваются на куски по 32 байта, затем все это объединяется вместе.
Например, возьмем функцию
function bar(bytes3[2]) public pure {}
Если бы мы хотели вызвать baz с параметрами 69 и true, мы бы передали всего 68 байт, которые можно разбить на:
0xcdcd77c0
: идентификатор метода. Это получается как первые 4 байта хэша Keccak формы ASCII подписи baz(uint32,bool).
0x0000000000000000000000000000000000000000000000000000000000000045
: первый параметр, значение uint32 69, дополненное до 32 байт.
0x0000000000000000000000000000000000000000000000000000000000000001
: второй параметр - boolean true, дополненный до 32 байтВ целом:
0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001
Для динамических аргументов вы кодируете их как их расположение в большом двоичном объекте calldata. Например:
function sam(bytes, bool, uint[]) public pure {}
Если бы мы хотели вызвать sam с аргументами «dave», true и [1,2,3], мы бы передали всего 292 байта, разбитых на:
0xa5643bf2
: идентификатор метода. Это происходит от сигнатуры sam(bytes,bool,uint256[]). Обратите внимание, что uint заменяется его каноническим представлением uint256.`0x000000000000000000000000000000000000000000000000000000000000000060: расположение части данных первого параметра (динамического типа), измеренное в байтах от начала блока аргументов. В данном случае 0x60.
0x0000000000000000000000000000000000000000000000000000000000000001
: второй параметр: boolean true.
0x00000000000000000000000000000000000000000000000000000000000000a0
: расположение части данных третьего параметра (динамического типа), измеренное в байтах. В этом случае0xa0
.
0x0000000000000000000000000000000000000000000000000000000000000004
: часть данных первого аргумента, она начинается с длины массива байтов в элементах, в данном случае 4.0x6461766500000000000000000000000000000000000000000000000000000000
: содержимое первого аргумента: кодировка UTF-8 (в данном случае равна ASCII) " dave", дополненный справа до 32 байт.
0x0000000000000000000000000000000000000000000000000000000000000003
: часть данных третьего аргумента, она начинается с длины массива в элементах, в данном случае 3.
0x0000000000000000000000000000000000000000000000000000000000000001
: первая запись третьего параметра.
0x0000000000000000000000000000000000000000000000000000000000000002
: вторая запись третьего параметра.
0x0000000000000000000000000000000000000000000000000000000000000003
: третья запись третьего параметра.В целом:
0xa5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003
Ник Джонсон