5

There is a tool on npm ethereum-input-data-decoder. And yes, i can read input data as hex

byte[] bytes = Hex.decodeHex(transactionReceipt.getInput().substring(2).toCharArray());
System.out.println(new String(bytes, "UTF-8"));

But i need structured output. Like json for example. I want to do it using java. Not npm

Ilya Khudyakov
  • 201
  • 2
  • 6

1 Answers1

3

Ok! I solved it.

First i created my own Contract, which is extend Contract from org.web3j.tx. Overrided two methods (i need to receive multiple values from contract): executeCallMultipleValueReturnAsync, executeCallMultipleValueReturn but with identical content as in Contract and created own executeCall method, which is identical to private executeCall from web3j Contract, but instead of pass DefaultBlockParameterName.LATEST to web3j.ethCall i am passing new DefaultBlockParameterNumber(blockNumber) with desired blockNumber as BigInteger. So here is:

    public class MyEthereumContract extends Contract {
    private String contractAddress;
    private BigInteger blockNumber;

    protected MyEthereumContract(String contractBinary, String contractAddress, Web3j web3j,
                               TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        super(contractBinary, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
    }

    protected MyEthereumContract(String contractBinary, String contractAddress, Web3j web3j, Credentials credentials,
                               BigInteger gasPrice, BigInteger gasLimit) {
        super(contractBinary, contractAddress, web3j, credentials, gasPrice, gasLimit);
    }

    protected MyEthereumContract(String contractBinary, String contractAddress, Web3j web3j, Credentials credentials,
                               BigInteger gasPrice, BigInteger gasLimit,
                               BigInteger blockNumber) {
        super(contractBinary, contractAddress, web3j, credentials, gasPrice, gasLimit);
        this.contractAddress = contractAddress;
        this.blockNumber = blockNumber;
    }

    @Override
    protected CompletableFuture<List<Type>> executeCallMultipleValueReturnAsync(Function function) {
        return Async.run(() -> executeCallMultipleValueReturn(function));
    }

    @Override
    protected List<Type> executeCallMultipleValueReturn(
            Function function) throws InterruptedException, ExecutionException {
        return executeCall(function);
    }

    private List<Type> executeCall(
            Function function) throws InterruptedException, ExecutionException {
        String encodedFunction = FunctionEncoder.encode(function);

        org.web3j.protocol.core.methods.response.EthCall ethCall = web3j.ethCall(
                Transaction.createEthCallTransaction(
                        transactionManager.getFromAddress(), contractAddress, encodedFunction),
                new DefaultBlockParameterNumber(blockNumber))
                .sendAsync().get();

        String value = ethCall.getValue();
        return FunctionReturnDecoder.decode(value, function.getOutputParameters());
    }
}

Than i added new constructor to class, generated from contract, which i am calling from load method

Ilya Khudyakov
  • 201
  • 2
  • 6