class EthereumWalletService {

    public BigInteger estimateGasLimit(String fromAddress, String toAddress, Function function, BigInteger weiValue) {
        try {
            EthEstimateGas ethEstimateGas = web3j.ethEstimateGas(new Transaction(fromAddress, null, null, null
                , toAddress, weiValue, FunctionEncoder.encode(function))).send();
            if (ethEstimateGas.getError() != null) {
                String parameters = function.getInputParameters().stream().map(TypeEncoder::encode).collect(Collectors.joining(","));
                userErrorMessageDao.add(new UserErrorMessage(null, fromAddress, ethEstimateGas.getError().getMessage(), function.getName(), parameters, System.currentTimeMillis()));
                throw new NotValidTransactionException(String.format("Unable to send eth transaction from %s to %s : %s, error - %s", fromAddress, toAddress, function.getName(), ethEstimateGas.getError().getMessage()));
            }
            BigInteger amountUsed = ethEstimateGas.getAmountUsed();
            return amountUsed.add(amountUsed.divide(BigInteger.TEN)); //+10%
        } catch (IOException e) {
            throw new RuntimeException("I/O error occurred, maybe eth node is down");
        }
    }

    @Inject public  EthereumWalletService(PropertiesHolder propertiesHolder, KeyStoreService keyStoreService, DexEthService dexEthService, UserErrorMessageDao userErrorMessageDao,
                                 DexBeanProducer dexBeanProducer);

}