25

I'm sending a transaction to an account with some data with the following command:

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

I'm getting this result, by extracting the log of the transaction (running with 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

I want to decode the last line "input" and try to get "http://localhost:8545". I saw some work similar to my question here and here, but this is not working in my case. Moreover, i tried .toString('hex')) but it remains as hex.

How can I achieve this?

Thanks in advance

12

You can do web3.toAscii(transactionID.input) to return the data in readable format.

Read web3.toAscii

4
  • 6
    This works with a transaction send through commandline, but when I send transactions to my contract by using web3 contract.addBalance.sendTransaction(contractAddress, {from: senderAddress, to: contractAddress, gas:1000000, value: web3.toWei(7, "ether"),data:web3.toHex("http://localhost:8545")}) if I try to get web3.toAscii(transaction.input) it returns some random symbolic values – SwapnilKumbhar May 19 '17 at 12:04
  • 1
    @SwapnilKumbhar check your data parameter. – niksmac May 19 '17 at 15:34
  • 1
    If you run into encoding issues using hexToAscii(), try using web3.hexToString()! Worked for me when neither toAscii or toUtf8 were behaving properly. – ohsully Jun 7 '19 at 21:10
  • 2
    depending on the version of web3 you're using, you may encounter the error web3.toAscii is not a function. To fix this issue, use web3.utils.toAscii() instead – adamc May 4 '20 at 14:26
17

In order to decode data you can use a library called abi-decoder

You will need to provide an ABI for the smart contract you want to decode, then just paste the input data. Very simple.

The only downfall would happen if your input data happens to be smart-contract creation "Constructor" then, in that case, you will have to change the library to accommodate with that.

3
6

We've made a nice tool for decoding. Just paste the transaction hash into input and get the result. Check it It works with Mainnet, Kovan, Ropsten and Rinkeby, but contract code must be verified in Etherscan. We use Etherscan API to get transaction and contract data, and web3 for decoding.

3
  • 4
    It is not recommended to write link only answers. If should be good if you add a little explanation about the page, like what tools/libraries you use for the decoder. – Ismael Jan 29 '18 at 18:46
  • 1
    @WTD It would be nice if it also accepted a raw transaction (signed and unsigned) as input, not only a tx hash. – Thorkil Værge Apr 11 '18 at 12:18
  • We just updated our tool. Now it is easy to check the data(input and output) of all calls that execute during the transaction. – WTD Oct 16 '18 at 17:34
6

If you've heard about the ethers js library, it provides a fantastic function named parseTransaction, I found it after a very long search as it wasn't mentioned in any online forums and I'm still learning a lot about this stuff.

But I found it to be the best for decoding any sort of contract and associated function call.

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

This JavaScript/Node.js library can decode smart contract input data and contract creation input data given the JSON abi:

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

3

A full definition of what you're trying to decode (the input data field) is here: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI. It's tough-going, but I was able to write some C++ that fully parses function arguments as recorded in the transactions. For your particular question, decoding the hex is correct, but for the more general case of the input data representing the function call and its parameters you have to decode the interface described in this document.

2
  • 5
    Your C++ doesn't happen to be open source does it? – Joël Jan 23 '17 at 8:18
  • 1
    Wow. It took me a year to answer, but "yes", it is open source (it wasn't in January). More information is here: quickblocks.io. – Thomas Jay Rush Dec 21 '17 at 0:54
3

UI Tools

Note for these you will need the ABI of the contract.

Node Packages

Recommendation

Use @ethersproject/abi, it's the safest approach of all. Ethers is battle-tested in thousands of Ethereum projects and there's likely no bug in its implementation of ABI encoding/ decoding.

1

In python, this is done using decode_function_input Contract method:

contract.decode_function_input(transaction.input)

see:

1
  • I don't see a contract in the original question, just a transaction. Aren't these two different things? – Fred Douglis Feb 7 '20 at 0:11
0

Consider using truffle and 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' }
  ]
}
*/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.