My use case is the following: I would like to have a daemon monitoring how users are interacting with my smart contract. The way I see it is to look at incoming blocks and try to decode input data with a to address corresponding to my contract. I was unable to find in web3J a way to decode data.

1- Is there any way with web3J to decode the data ?

2- Have I any other way to achieve my goal than decode the input data ? Events seems to me as an hard choice as I will not be able to easily monitor every things. And this methods cannot apply to smart contract that I don't own.

Thanks for the help.

  • 1
    A proposal for JS exists already abi-decoder answer. Doing a crawler in JS that is regularly pushing data is an option.
    – Cyril
    Nov 22 '17 at 13:51
  • 1
    An suggestion was also already done for web3j here. However it does not help with the compatibility with the library.
    – Cyril
    Nov 22 '17 at 13:53

I guess sort of for the first question. If you look at what a transaction is, to a node its just a big long byte string. If the bytes are convertible to ASCII, you can use use the


That may or may not give you something. For instance, here's a tx a I did on Ropsten where you get some readable input data back and some non-readable data: https://ropsten.etherscan.io/tx/0xe4058b8f612f20600d8aae1230d93b7b5c63398ddde0a3a6aed236659f425c0e (just click the input Convert to Ascii at the bottom)

That said, the best (easiest) way to do this is to own the dapp. So when they fill out a form, you just save the input data. The next best like you said is to use Events. They are annoying, but you could have just one long event at the beginning of your contracts:

    contract Test {
       event Input(string desc, address _party, uint _input1, string _input2);  

     function somefunc(uint _input1, string _input2) returns(bool success){
      return true;

But then for other people's contracts your out of luck since you don't have this event.

  • 2
    Thanks you for the answer. I've just added an new issue on web3j github for implementing such a possibility. Looking at the code it does not look too hard to reverse engineer some functions and decode the string. What is encoded is function <name> , parameters value.
    – Cyril
    Nov 22 '17 at 13:48
  • 1
  • 2
    Awesome, great stuff to know. It seems like you'll be ok trying to decode it as long as the contract isn't intentionally trying to hide the inputs
    – thefett
    Nov 22 '17 at 15:05
  • 1
    Even in this case, I don't mind too much. I will extract the input and offer the input to users as they might have authority to access it that my server app hasn't.
    – Cyril
    Nov 22 '17 at 15:11
    ERC20 javaToken = ERC20.load(contractAddress, web3, creds, new DefaultGasProvider());
    System.out.println("ALL HISTORY OF TT");
    javaToken.transferEventFlowable(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST)
     -> System.out.println("from: " + event._from + ", to: " + event._to + ", value: " + event._value));    

I think this will help you


The logic that I have used is as follows:

web3j.transactionflowable.subscribe(tx -> {

checkIfMyTransaction(tx.getTo, tx.getHash);


public void checkIfMyTransaction(String toAddress, String txHash){

// check data base if the address belong to my application and then following logic. This can be contract address or wallet address. 

// if contract address:

EthTransaction ethTransaction=web3j.getTransactionByHash(txHash).send;
Transaction transaction=ethTransaction.getTransaction.get();

// Take all info like blocknumber, blockhash etc from above call. For input data, we create new method. 


public void decodeInput(String data) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    String inputData = data;
    String method = inputData.substring(0,10);
    log.info("Method >>>>>> " +method);
    String to = inputData.substring(10,74);
    String value = inputData.substring(74);
    Method refMethod = TypeDecoder.class.getDeclaredMethod("decode",String.class,int.class,Class.class);
    Address address = (Address)refMethod.invoke(null,to,0,Address.class);
    log.info("Address>>>>>> " +address.toString());
    Uint256 amount = (Uint256) refMethod.invoke(null,value,0,Uint256.class);
    log.info("amount >>>>>> " +amount);

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.