Go-Ethereum
從合約 web3j 返回的空值 (0x)
我正在嘗試使用Web3j 4.2.0在 Windows 10 上部署一個非常簡單的契約。我已經使用 Mist 創建了一個帳戶。我已經在我的機器上設置了一個本地乙太坊節點(使用geth),並且我能夠使案例如部署合約並與之互動。薄霧。但是當我一直試圖從 Java 程式碼中做同樣的事情時,我得到
org.web3j.tx.exceptions.ContractCallException: Empty value (0x) returned from contract at org.web3j.tx.Contract.executeCallSingleValueReturn(Contract.java:250) at org.web3j.tx.Contract.lambda$executeRemoteCallSingleValueReturn$1(Contract.java:317) at org.web3j.protocol.core.RemoteCall.send(RemoteCall.java:30)
這是我的穩固契約:
pragma solidity ^0.5.5; contract SampleContract{ uint256 sampleVariable = 0; function setSample(uint256 x) public{ sampleVariable = x; } function getSample() public view returns(uint256){ return sampleVariable; } }
我使用solidity編譯器和web3j CLI 4.2.0創建了一個java包裝類:
/** * <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 SampleContract extends Contract { private static final String BINARY = "60806040526000805534801561001457600080fd5b5060a2806100236000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806331c8039b146037578063e221818b14604f575b600080fd5b603d606b565b60408051918252519081900360200190f35b606960048036036020811015606357600080fd5b50356071565b005b60005490565b60005556fea165627a7a72305820de9e3ced16dc30cb74a4215c04b4b6f5f61df43a4bc0c38fbbd23e798b6b805d0029"; public static final String FUNC_GETSAMPLE = "getSample"; public static final String FUNC_SETSAMPLE = "setSample"; @Deprecated protected SampleContract(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); } protected SampleContract(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) { super(BINARY, contractAddress, web3j, credentials, contractGasProvider); } @Deprecated protected SampleContract(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); } protected SampleContract(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) { super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider); } public RemoteCall<BigInteger> getSample() { final Function function = new Function(FUNC_GETSAMPLE, Arrays.<Type>asList(), Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {})); return executeRemoteCallSingleValueReturn(function, BigInteger.class); } public RemoteCall<TransactionReceipt> setSample(BigInteger x) { final Function function = new Function( FUNC_SETSAMPLE, Arrays.<Type>asList(new Uint256(x)), Collections.<TypeReference<?>>emptyList()); return executeRemoteCallTransaction(function); } @Deprecated public static SampleContract load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { return new SampleContract(contractAddress, web3j, credentials, gasPrice, gasLimit); } @Deprecated public static SampleContract load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { return new SampleContract(contractAddress, web3j, transactionManager, gasPrice, gasLimit); } public static SampleContract load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) { return new SampleContract(contractAddress, web3j, credentials, contractGasProvider); } public static SampleContract load(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) { return new SampleContract(contractAddress, web3j, transactionManager, contractGasProvider); } public static RemoteCall<SampleContract> deploy(Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) { return deployRemoteCall(SampleContract.class, web3j, credentials, contractGasProvider, BINARY, ""); } @Deprecated public static RemoteCall<SampleContract> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { return deployRemoteCall(SampleContract.class, web3j, credentials, gasPrice, gasLimit, BINARY, ""); } public static RemoteCall<SampleContract> deploy(Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) { return deployRemoteCall(SampleContract.class, web3j, transactionManager, contractGasProvider, BINARY, ""); } @Deprecated public static RemoteCall<SampleContract> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { return deployRemoteCall(SampleContract.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, ""); } }
下面是合約創建的java程式碼:
Credentials credentials = WalletUtils.loadCredentials(password, keystorePath); SampleContract sampleContract= SampleContract.deploy(web3j, credentials, new DefaultGasProvider()).send(); LOGGER.info("Contract deployed under address: " + sampleContract.getContractAddress()); LOGGER.info("Is contract valid : " + sampleContract.isValid()); BigInteger sampleNumber = sampleContract.getSample().send();
我能夠部署契約,獲取它的地址,還檢查這個契約是否有效返回 true。但是當我嘗試從中讀取(最後一行程式碼)時,它總是拋出 org.web3j.tx.exceptions.ContractCallException。你知道這是什麼原因嗎?感謝幫助。
使用 SampleContract Wrapper 中的 load(…) 方法,然後呼叫 getSample()
我現在無法測試它,但它應該看起來像這樣
// your code for deploy and wait until it deployed SampleContract myContract = SampleContract.load(<your-contract-address>, web3j, credentails, ......etc); BigInteger sNumber = myContract.getSample().send(); //or BigInteger sNumber = myContract.getSample().sendAsync().get();
你有沒有解決這個問題。我也有同樣的問題