Private-Blockchain

“所需的氣體超過限額或總是失敗的交易”是什麼問題

  • January 8, 2022

我使用 solc 和 web3j 將智能合約翻譯成 Java,但我遇到了“所需的氣體超過限額或交易總是失敗”的問題。

這是我的智能合約。

在此處輸入圖像描述

當我使用 Remix 在我的私有鏈上部署時,它是有效的。當我使用 solc 和 web3j 將智能合約翻譯成 Java 時,這個 Java 版本不起作用。

我的作業系統版本:Ubuntu 18.04.2 LTS

我的 solc 版本:0.5.7+commit.6da8b019.Linux.g++

我的 web3j 版本:4.2.0

智能合約Java程式碼:

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;
}
}

我的 GasProvider Java 程式碼:

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);
}
}

這是用於部署和使用智能合約的 Java 程式碼。

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

}
}

馬文:

<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>

程序結果

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'}

我的交易日誌為空,結果是通過 Remix 與智能合約 adderss 互動。

在此處輸入圖像描述

煤氣都用完了,但契約花不了多少錢。我覺得很奇怪,不知道會發生什麼。請給我一些建議。謝謝你的幫助。

您可以將 Solidity 版本從 “0.5.7+commit.6da8b019.Linux.g++” 更改為以前的版本(如***“0.5.2+commit.1df8f40c.Emscripten.clang”***),這將解決問題。

您可以檢查 geth 節點日誌以找出實際問題。

我遇到了類似的問題,錯誤是err=“invalid opcode 0x1c”

您可以使用以前的編譯器版本從 remix 中部署智能合約,並使用 java 中的合約地址來載入合約以解決錯誤。

或者您可能需要更新您的 geth 版本以支持新功能。

希望這會有所幫助

該操作碼是最近在君士坦丁堡版本中添加到 geth 的。您需要將以下內容添加到您的 genesis 以啟用君士坦丁堡:

 "constantinopleBlock":0,

引用自:https://ethereum.stackexchange.com/questions/69111