¿Cómo decodificar los datos de entrada de una transacción?

Estoy enviando una transacción a una cuenta con algunos datos con el siguiente comando:

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

Obtengo este resultado al extraer el registro de la transacción (ejecutándose con 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

Quiero decodificar la última línea "entrada" e intentar obtener " http://localhost:8545 ". Vi un trabajo similar a mi pregunta aquí y aquí , pero esto no funciona en mi caso. Además, lo intenté .toString('hex'))pero sigue siendo hexadecimal.

¿Cómo puedo conseguir esto?

Gracias por adelantado

Respuestas (11)

Puede hacer web3.toAscii(transactionID.input)para devolver los datos en formato legible.

Leer web3.toAscii

Esto funciona con un envío de transacciones a través de la línea de comandos, pero cuando envío transacciones a mi contrato usando web3 contract.addBalance.sendTransaction(contractAddress, {from: senderAddress, to: contractAddress, gas:1000000, value: web3.toWei(7, "ether"),data:web3.toHex("http://localhost:8545")})si trato de obtener web3.toAscii (transacción. entrada) devuelve algunos valores simbólicos aleatorios
@SwapnilKumbhar verifique su parámetro de datos.
Si tiene problemas de codificación al usar hexToAscii(), intente usar web3.hexToString()! Funcionó para mí cuando ninguno de toAsciilos dos toUtf8se comportaba correctamente.
dependiendo de la versión de web3 que esté utilizando, es posible que encuentre el error web3.toAscii is not a function. Para solucionar este problema, utilice en su web3.utils.toAscii()lugar

Para decodificar datos, puede usar una biblioteca llamada abi-decoder

Deberá proporcionar un ABI para el contrato inteligente que desea decodificar, luego simplemente pegue los datos de entrada. Muy simple.

La única desventaja ocurriría si sus datos de entrada fueran "Constructor" de creación de contrato inteligente, entonces, en ese caso, tendrá que cambiar la biblioteca para adaptarse a eso.

¿Cuál es la mejor manera de decodificar los datos de creación de contratos inteligentes?
La mejor manera, en ese caso, es usar mi versión de la biblioteca mencionada anteriormente. Puede encontrarla aquí, solo impórtela y úsela en su proyecto. Funcionará github.com/Neufund/smart-contract-watch/blob/master /fuente/…
desafortunadamente, la solución que presentó no funcionó github.com/Neufund/smart-contract-watch/issues/70

Si ha oído hablar de la biblioteca ethers js , proporciona una función fantástica llamada parseTransaction , la encontré después de una búsqueda muy larga ya que no se mencionó en ningún foro en línea y todavía estoy aprendiendo mucho sobre esto.

Pero descubrí que es lo mejor para decodificar cualquier tipo de contrato y llamada de función asociada.

    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])
          });        
    })();

Herramientas de interfaz de usuario

Tenga en cuenta que para estos necesitará el ABI del contrato.

Paquetes de nodos

Recomendación

Use @ethersproject/abi, es el enfoque más seguro de todos. Ethers ha sido probado en batalla en miles de proyectos de Ethereum y es probable que no haya ningún error en su implementación de codificación/descodificación ABI.

Hemos hecho una buena herramienta para decodificar. Simplemente pegue el hash de la transacción en la entrada y obtenga el resultado. Verifíquelo Funciona con Mainnet, Kovan, Ropsten y Rinkeby, pero el código del contrato debe verificarse en Etherscan. Usamos la API de Etherscan para obtener datos de transacciones y contratos, y web3 para la decodificación.

No se recomienda escribir respuestas de solo enlace. Si debería ser bueno si agrega una pequeña explicación sobre la página, como qué herramientas/bibliotecas usa para el decodificador.
@WTD Sería bueno si también aceptara una transacción sin procesar (firmada y sin firmar) como entrada, no solo un hash tx.
Acabamos de actualizar nuestra herramienta. Ahora es fácil verificar los datos (entrada y salida) de todas las llamadas que se ejecutan durante la transacción.
Parece que esta herramienta ya no funciona: pegar un txid y hacer clic en "Decodificar" no hace nada.

Esta biblioteca de JavaScript/Node.js puede decodificar datos de entrada de contratos inteligentes y datos de entrada de creación de contratos dado el JSON abi:

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

Una definición completa de lo que está tratando de decodificar (el campo de datos de entrada) está aquí: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI . Es difícil, pero pude escribir algo de C ++ que analiza completamente los argumentos de función tal como se registran en las transacciones. Para su pregunta particular, decodificar el hexadecimal es correcto, pero para el caso más general de los datos de entrada que representan la llamada a la función y sus parámetros, debe decodificar la interfaz descrita en este documento.

Su C ++ no es de código abierto, ¿verdad?
Guau. Me tomó un año responder, pero "sí", es de código abierto (no fue en enero). Más información está aquí: quickblocks.io .

En python, esto se hace usando el método de contrato decode_function_input:

contract.decode_function_input(transaction.input)

ver:

No veo un contrato en la pregunta original, solo una transacción. ¿No son estas dos cosas diferentes?

Considere usar truffle y 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' }
  ]
}
*/

estoy usando"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)}`
    );

Los primeros 4 bytes de entrada son la firma del método

producción:

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

Documentos: https://web3js.readthedocs.io/en/v1.2.11/web3-eth-abi.html#decodeparameters

Usar tiernamente es una buena opción. Si agrega un contrato verificado (o tiene las fuentes/abi para agregar directamente), puede proporcionar datos de transacción sin procesar y ejecutar una simulación con él, y le mostrará cómo se decodifica la entrada.