Как декодировать входные данные из транзакции?

Я отправляю транзакцию на счет с некоторыми данными с помощью следующей команды:

eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(1,"ether"),data:web3.toHex("http://localhost:8545")})

Я получаю этот результат, извлекая журнал транзакции (работая с testRPC):

   tx hash         : 0xf654aee5ed23f9aeebd2d73c69c7b9c21a4862787966d09bcb09ed44efc1f252
   nonce           : 0
   blockHash       : 0x6ff8a0e3ac606abd2ede4331b82af52a0daa98448025051fb3b3d50f749aa49f
   blockNumber     : 1
   transactionIndex: 0
   from            : 0xf64918835bc21dff9e8210a807b3964d1be35dd0
   to              : 0x08f986b7535c2b72687d3cb193135f1c6e27c336
   value           : 1000000000000000000
   time            : 1483614904 Thu, 05 Jan 2017 11:15:04 GMT
   gasPrice        : 1
   gas             : 90000
   input           : 0x687474703a2f2f6c6f63616c686f73743a38353435

Я хочу декодировать последнюю строку «ввод» и попытаться получить « http://localhost:8545 ». Я видел некоторые работы, похожие на мой вопрос здесь и здесь , но это не работает в моем случае. Более того, я пытался, .toString('hex'))но он остается шестнадцатеричным.

Как я могу этого добиться?

заранее спасибо

Ответы (11)

Вы можете сделать, web3.toAscii(transactionID.input)чтобы вернуть данные в читаемом формате.

Читать web3.toAscii

Это работает с транзакцией, отправляемой через командную строку, но когда я отправляю транзакции в свой контракт с помощью web3 contract.addBalance.sendTransaction(contractAddress, {from: senderAddress, to: contractAddress, gas:1000000, value: web3.toWei(7, "ether"),data:web3.toHex("http://localhost:8545")}), если я пытаюсь получить web3.toAscii(transaction.input), он возвращает некоторые случайные символические значения.
@SwapnilKumbhar проверьте свой параметр данных.
Если у вас возникли проблемы с кодировкой при использовании hexToAscii(), попробуйте использовать web3.hexToString()! Работал для меня, когда ни toAsciiто , ни другое не toUtf8вели себя должным образом.
в зависимости от версии web3, которую вы используете, вы можете столкнуться с ошибкой web3.toAscii is not a function. Чтобы решить эту проблему, используйте web3.utils.toAscii()вместо этого

Для декодирования данных вы можете использовать библиотеку под названием abi-decoder .

Вам нужно будет предоставить ABI для смарт-контракта, который вы хотите декодировать, а затем просто вставьте входные данные. Очень простой.

Единственное падение произойдет, если ваши входные данные окажутся созданием смарт-контракта «Конструктор», тогда в этом случае вам придется изменить библиотеку, чтобы приспособиться к этому.

как лучше всего расшифровать данные создания смарт-контракта?
В этом случае лучше всего использовать мою версию упомянутой выше библиотеки, которую вы можете найти здесь, просто импортируйте ее и используйте в своем проекте, она будет работать github.com/Neufund/smart-contract-watch/blob/master /источник/…
к сожалению, представленное вами решение не сработало github.com/Neufund/smart-contract-watch/issues/70

Если вы слышали о библиотеке ethers js , она предоставляет фантастическую функцию с именем parseTransaction. Я нашел ее после очень долгих поисков, так как она не упоминалась ни на одном онлайн-форуме, и я все еще многому учусь.

Но я обнаружил, что это лучше всего подходит для декодирования любого вида контракта и связанного с ним вызова функции.

    const ethers = require('ethers');
    const ABI = require('./abi.json'); // Contract ABI
    const provider = ethers.getDefaultProvider();

    const inter = new ethers.utils.Interface(ABI);

    (async() => {
      const tx = await provider.getTransaction('0xa30e9e19967bd3307feeddcf99b26be0d804cdc0ade6929f3b9328a95e388b4c');
        const decodedInput = inter.parseTransaction({ data: tx.data, value: tx.value});
    
        // Decoded Transaction
        console.log({
            function_name: decodedInput.name,
            from: tx.from,
            to: decodedInput.args[0],
            erc20Value: Number(decodedInput.args[1])
          });        
    })();

Инструменты пользовательского интерфейса

Обратите внимание, что для этого вам понадобится ABI контракта.

Пакеты узлов

Рекомендация

Используйте @ethersproject/abi, это самый безопасный подход из всех. Эфиры протестированы в тысячах проектов Ethereum, и, скорее всего, в его реализации кодирования/декодирования ABI нет ошибок.

Мы сделали хороший инструмент для декодирования. Просто вставьте хэш транзакции в поле ввода и получите результат. Проверьте это . Он работает с Mainnet, Kovan, Ropsten и Rinkeby, но код контракта должен быть проверен в Etherscan. Мы используем API Etherscan для получения данных о транзакциях и контрактах, а также web3 для декодирования.

Не рекомендуется писать ссылки только на ответы. Было бы хорошо, если бы вы добавили небольшое объяснение о странице, например, какие инструменты/библиотеки вы используете для декодера.
@WTD Было бы неплохо, если бы он также принимал необработанную транзакцию (подписанную и неподписанную) в качестве входных данных, а не только хэш tx.
Мы только что обновили наш инструмент. Теперь легко проверить данные (входные и выходные) всех вызовов, которые выполняются во время транзакции.
Кажется, что этот инструмент больше не работает — вставка txid и нажатие «Декодировать» ничего не дает.

Эта библиотека JavaScript/Node.js может декодировать входные данные смарт-контракта и входные данные создания контракта с учетом JSON abi:

https://github.com/miguelmota/ethereum-input-data-decoder

Полное определение того, что вы пытаетесь декодировать (поле входных данных), находится здесь: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI . Это непросто, но мне удалось написать код на C++, который полностью анализирует аргументы функций, записанные в транзакциях. Для вашего конкретного вопроса декодирование шестнадцатеричного кода является правильным, но для более общего случая входных данных, представляющих вызов функции и ее параметры, вам необходимо декодировать интерфейс, описанный в этом документе.

Ваш C++ случайно не с открытым исходным кодом, не так ли?
Ух ты. Мне понадобился год, чтобы ответить, но «да», это с открытым исходным кодом (в январе этого не было). Больше информации здесь: quickblocks.io .

В python это делается с помощью метода контракта decode_function_input:

contract.decode_function_input(transaction.input)

видеть:

Я не вижу контракта в исходном вопросе, просто транзакцию. Разве это не две разные вещи?

Рассмотрите возможность использования truffle и abi-decoder :

# compile contracts to generate ABIs
truffle compile

# let's do it from truffle console
truffle console

const abiDecoder = require('abi-decoder');

# take ABIs of required contracts
const { abi: abi1 } = require('./build/contracts/sc1.json');
const { abi: abi2 } = require('./build/contracts/sc2.json');
..

# register ABIs
abiDecoder.addABI(abi1);
abiDecoder.addABI(abi2);
..

# take 'TX data' of transaction & decode it (take for example the first transaction in  100th block)

let input = (await web3.eth.getTransactionFromBlock(100, 0)).input

abiDecoder.decodeMethod(input);

/* result
{
  name: 'request',
  params: [
    { name: '_control', value: 'control', type: 'string' },
    { name: '_tId', value: 'tid', type: 'string' },
    { name: '_number', value: 'inumber', type: 'string' }
  ]
}
*/

Я использую"web3": "^1.6.1",

const data = await web3.eth.getTransaction(txHash);
return web3.eth.abi.decodeParameters(
      // ERC20 transfer method args
      [
        { internalType: 'address', name: 'recipient', type: 'address' },
        { internalType: 'uint256', name: 'amount', type: 'uint256' },
      ],
      `0x${txData.input.substring(10)}`
    );

Первые 4 байта ввода — это сигнатура метода.

выход:

 {
    "0": "0x45d8253c7980d5718C5Fa3626d446886Fd857CfE",
    "1": "160750000000000000000",
    "__length__": 2,
    "recipient": "0x45d8253c7980d5718C5Fa3626d446886Fd857CfE",
    "amount": "160750000000000000000"
  }

Документы: https://web3js.readthedocs.io/en/v1.2.11/web3-eth-abi.html#decodeparameters

Использование нежно является хорошим вариантом. Если вы добавите подтвержденный контракт (или у вас есть abi/источники, которые нужно добавить напрямую), вы можете предоставить необработанные данные транзакции и запустить с ними симуляцию, и она покажет вам, как декодируются входные данные.