0

I translate smart contract into Java with solc and web3j, but I meet the probelm "gas required exceeds allowance or always failing transaction".

This is my smart contract.

enter image description here

It is work when I use Remix to deploy at my private chain. When I translate smart contract into Java with solc and web3j , this Java version is not work.

My os version : Ubuntu 18.04.2 LTS

My solc version : 0.5.7+commit.6da8b019.Linux.g++

My web3j version : 4.2.0

Java code of smart contract :

import io.reactivex.Flowable;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.web3j.abi.EventEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Event;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.RemoteCall;
import org.web3j.protocol.core.methods.request.EthFilter;
import org.web3j.protocol.core.methods.response.Log;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.Contract;
import org.web3j.tx.TransactionManager;
import org.web3j.tx.gas.ContractGasProvider;

/**
* <p>Auto generated code.
* <p><strong>Do not modify!</strong>
* <p>Please use the <a href="https://docs.web3j.io/command_line.html">web3j 
command line tools</a>,
* or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the 
* <a href="https://github.com/web3j/web3j/tree/master/codegen">codegen 
module</a> to update.
*
* <p>Generated with web3j version 4.2.0.
*/

public class Hello extends Contract {
private static final String BINARY = "60806040526005600055348015601457600080fd5b506098806100236000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806313bdfacd14602d575b600080fd5b60336035565b005b60005460408051918252517f909c57d5c6ac08245cf2a6de3900e2b868513fa59099b92b27d8db823d92df9c9181900360200190a156fea165627a7a723058203b5d233e1ef9461ed0361b73be5990af6f29a72874bd3a87184a427417c991a50029";


public static final String FUNC_PRINT = "print";

public static final Event LOG_EVENT = new Event("Log", 
        Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
;

@Deprecated
protected Hello(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
    super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
}

protected Hello(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
    super(BINARY, contractAddress, web3j, credentials, contractGasProvider);
}

@Deprecated
protected Hello(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
    super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
}

protected Hello(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
    super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider);
}

public RemoteCall<TransactionReceipt> print() {
    final Function function = new Function(
            FUNC_PRINT, 
            Arrays.<Type>asList(), 
            Collections.<TypeReference<?>>emptyList());
    return executeRemoteCallTransaction(function);
}

public List<LogEventResponse> getLogEvents(TransactionReceipt transactionReceipt) {
    List<Contract.EventValuesWithLog> valueList = extractEventParametersWithLog(LOG_EVENT, transactionReceipt);
    ArrayList<LogEventResponse> responses = new ArrayList<LogEventResponse>(valueList.size());
    for (Contract.EventValuesWithLog eventValues : valueList) {
        LogEventResponse typedResponse = new LogEventResponse();
        typedResponse.log = eventValues.getLog();
        typedResponse.txmessage = (BigInteger) eventValues.getNonIndexedValues().get(0).getValue();
        responses.add(typedResponse);
    }
    return responses;
}

public Flowable<LogEventResponse> logEventFlowable(EthFilter filter) {
    return web3j.ethLogFlowable(filter).map(new io.reactivex.functions.Function<Log, LogEventResponse>() {
        @Override
        public LogEventResponse apply(Log log) {
            Contract.EventValuesWithLog eventValues = extractEventParametersWithLog(LOG_EVENT, log);
            LogEventResponse typedResponse = new LogEventResponse();
            typedResponse.log = log;
            typedResponse.txmessage = (BigInteger) eventValues.getNonIndexedValues().get(0).getValue();
            return typedResponse;
        }
    });
}

public Flowable<LogEventResponse> logEventFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
    EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress());
    filter.addSingleTopic(EventEncoder.encode(LOG_EVENT));
    return logEventFlowable(filter);
}

@Deprecated
public static Hello load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
    return new Hello(contractAddress, web3j, credentials, gasPrice, gasLimit);
}

@Deprecated
public static Hello load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
    return new Hello(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
}

public static Hello load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
    return new Hello(contractAddress, web3j, credentials, contractGasProvider);
}

public static Hello load(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
    return new Hello(contractAddress, web3j, transactionManager, contractGasProvider);
}

public static RemoteCall<Hello> deploy(Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
    return deployRemoteCall(Hello.class, web3j, credentials, contractGasProvider, BINARY, "");
}

@Deprecated
public static RemoteCall<Hello> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
    return deployRemoteCall(Hello.class, web3j, credentials, gasPrice, gasLimit, BINARY, "");
}

public static RemoteCall<Hello> deploy(Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
    return deployRemoteCall(Hello.class, web3j, transactionManager, contractGasProvider, BINARY, "");
}

@Deprecated
public static RemoteCall<Hello> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
    return deployRemoteCall(Hello.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "");
}

public static class LogEventResponse {
    public Log log;

    public BigInteger txmessage;
}
}

My GasProvider Java code :

import java.math.BigInteger;
import org.web3j.tx.Contract;
import org.web3j.tx.gas.StaticGasProvider;

public class myGasProvider extends StaticGasProvider {
public static final BigInteger GAS_LIMIT = BigInteger.valueOf(3000000);
public static final BigInteger GAS_PRICE = BigInteger.valueOf(0);

public myGasProvider() {
    super(GAS_PRICE, GAS_LIMIT);
}
}

This is Java code for deploying and using the smart contract.

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.omg.CORBA.Environment;
import org.web3j.abi.datatypes.Uint;
import org.web3j.abi.datatypes.Utf8String;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.gas.ContractGasProvider;
import org.web3j.tx.gas.DefaultGasProvider;
import jnr.unixsocket.Credentials;

public class QuickStart {

private static Web3j web3j;

public static void main(String[] args) throws Exception {
    web3j = Web3j.build(new HttpService("http://192.168.80.128:8545/"));
    Web3ClientVersion web3ClientVersion = null;
    try {
        web3ClientVersion = web3j.web3ClientVersion().send();
        String clientVersion = web3ClientVersion.getWeb3ClientVersion();
        System.out.println("clientVersion " + clientVersion);
        String filePath = "./key/";
        String fileName;
        fileName = WalletUtils.generateNewWalletFile("123456", new File(filePath), false);
        org.web3j.crypto.Credentials credentials = WalletUtils.loadCredentials("123456",filePath+fileName);
        //System.out.println(fileName);//保存你的加密文件信息
        System.out.println("Eth address: "+credentials.getAddress());//钱包地址
        System.out.println("Eth address private key: "+credentials.getEcKeyPair().getPrivateKey());//私钥
        System.out.println("Eth address public key: "+credentials.getEcKeyPair().getPublicKey());//公钥
        ContractGasProvider contractGasProvider = new myGasProvider();
        //BigInteger GAS_LIMIT = BigInteger.valueOf(3000000);
        //BigInteger GAS_PRICE = BigInteger.valueOf(0);
        Hello contract= Hello.deploy(web3j, credentials,contractGasProvider).send();
        System.out.println("Smart Contrac address:"+contract.getContractAddress());
        System.out.println("Smart Contrac Usage:"+contract.isValid());
        TransactionReceipt transactionReceipt=contract.print().send();
        System.out.println("transaction hash:"+transactionReceipt.getTransactionHash());            
        System.out.println("transaction data:"+transactionReceipt.toString());          
    } catch (IOException e) {
        e.printStackTrace();
    }

}
}

Maven :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Test</groupId>
<artifactId>Test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
      <source>1.8</source>
      <target>1.8</target>
    </configuration>
  </plugin>
 </plugins>
</build>
<dependencies>
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>2.1.12</version>
</dependency>
</dependencies>  
</project>

program result

clientVersion Geth/v1.9.0-unstable-9a58a9b9/linux-amd64/go1.10.4
Eth address: 0xe2232ad9fd8a2e7c879500ddbf146670244798ab
Eth address private key: 47678188744480457656968595668529367483035979819489762803117503272466348282724
Eth address public key: 9875770019807071285812783255049855080295070551278042833113719057002229716018811513481131655753052174064293298860327874461667018196051277952135391995718979
Smart Contract address:0xef8b6c0d7adad1b416b21806d3cb6d541ba26a19
Smart Contract Usage:true
transaction hash:0xf9f50c7823cb77a612ae91d721058eb15003135c858bbb4fb6af616bddc93ff8
transaction data:TransactionReceipt{transactionHash='0xf9f50c7823cb77a612ae91d721058eb15003135c858bbb4fb6af616bddc93ff8', transactionIndex='0x0', blockHash='0x60f1b8664edb0a76231f97262f7861ae12b3de3632f71489dd7eb2b517d6d51f', blockNumber='0x2a0', cumulativeGasUsed='0x2dc6c0', gasUsed='0x2dc6c0', contractAddress='null', root='0xb028fd4ac6173b30c8945fb988d408238f794faccbc20805e81cc57146fced7c', status='null', from='0xe2232ad9fd8a2e7c879500ddbf146670244798ab', to='0xef8b6c0d7adad1b416b21806d3cb6d541ba26a19', logs=[], logsBloom='0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'}

My transaction log is null and Interacting the smart contract adderss by Remix is the result.

enter image description here

The gas is all used ,but the contract don't cost much . I feel weird and don't know what happens. Please give me some advice . Thank you for help.

  • advice: dont use remix – Majd TL Apr 7 at 11:39
0

You can change the solidity version from "0.5.7+commit.6da8b019.Linux.g++" to some previous version (like "0.5.2+commit.1df8f40c.Emscripten.clang") which will resolve the problem.

You can check the geth node log to find out the actual problem.

I have faced a similar problem where the error was err="invalid opcode 0x1c"

You can deploy the smart contract from the remix with a previous compiler version and use the contract address in java to load the contract to resolve the error.

Or you may need to update your geth version to support the new features.

Hope this will help

  • Thanks. There is the success by deploying the smart contract from the remix and loading it with Java but I must deploy the smart contract by Java. I will try different solidity versions. Thanks for your advice. – hjhjgj May 18 at 5:23
0

That opcode is a recent addition to geth in the Constantinople release. You need to add the following to your genesis to enable Constantinople:

  "constantinopleBlock":0,

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.