合約錯誤:org.web3j.protocol.exceptions.TransactionException:Error processing request:unknown transaction
阿新 • • 發佈:2019-01-06
在執行一個 ERC20 智慧合約的transfer呼叫時發生的org.web3j的一個交易錯誤:
org.web3j.protocol.exceptions.TransactionException: Error processing request: unknown transaction
。
Credentials credentials = null;
try {
this.initWeb3Client();
credentials = WalletUtils.loadCredentials(pwd, path);
MyToken mt = MyToken.load(ADDRESS,web3j,
credentials, BigInteger.valueOf(20_000_000_000L),BigInteger.valueOf(4_300_000L));
TransactionReceipt tr = oso.transfer(address,value).send();
System.out.println("hash:"+tr.getTransactionHash());
} catch (IOException e) {
e.printStackTrace ();
} catch (CipherException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
交易被成功的提交到了Rinkeby測試鏈上,但是丟擲了這個錯誤資訊:
org.web3j.protocol.exceptions.TransactionException: Error processing request: unknown transaction
at org.web 3j.tx.response.TransactionReceiptProcessor.sendTransactionReceiptRequest(TransactionReceiptProcessor.java:32)
at org.web3j.tx.response.PollingTransactionReceiptProcessor.getTransactionReceipt(PollingTransactionReceiptProcessor.java:37)
at org.web3j.tx.response.PollingTransactionReceiptProcessor.waitForTransactionReceipt(PollingTransactionReceiptProcessor.java:29)
at org.web3j.tx.TransactionManager.processResponse(TransactionManager.java:72)
at org.web3j.tx.TransactionManager.executeTransaction(TransactionManager.java:51)
at org.web3j.tx.ManagedTransaction.send(ManagedTransaction.java:70)
at org.web3j.tx.Contract.executeTransaction(Contract.java:223)
at org.web3j.tx.Contract.executeTransaction(Contract.java:207)
at org.web3j.tx.Contract.executeTransaction(Contract.java:201)
at org.web3j.tx.Contract.lambda$executeRemoteCallTransaction$3(Contract.java:240)
at org.web3j.protocol.core.RemoteCall.send(RemoteCall.java:30)
at com.novel.balbit.ports.contract.MyTokenTest.transfer(MyTokenTest.java:358)
at com.novel.balbit.ports.contract.MyTokenTest.main(MyTokenTest.java:396)
問題可能解決方法
這個問題應該發生在TransactionReceiptProcessor
內部。
當呼叫web3j.ethGetTransactionReceipt(transactionHash).send()
時內部會執行waitForTransactionReceipt
。
你的節點可能還沒有徹底準備好,無法給你提供一個有效的TransactionReceipt
。
你可以通過手動構建交易來解決這個問題:
Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/
Credentials credentials = WalletUtils.loadCredentials("password", "/path/to/walletfile");
// get the next available nonce
EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(
address, DefaultBlockParameterName.LATEST).sendAsync().get();
BigInteger nonce = ethGetTransactionCount.getTransactionCount();
// create our transaction
RawTransaction rawTransaction = RawTransaction.createEtherTransaction(
nonce, <gas price>, <gas limit>, <toAddress>, <value>);
// sign & send our transaction
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Hex.toHexString(signedMessage);
// FROM here you can get the tx hash.
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();
雖然可以使用自定義的交易管理器,但儘量嘗試更改輪詢的次數來增加獲得txhash
的概率。
public static final int DEFAULT_POLLING_ATTEMPTS_PER_TX_HASH = 40;
public static final long DEFAULT_POLLING_FREQUENCY = 1000 * 15;
例如:
new Transfer(client, new ClientTransactionManager(client ,fromAddress, 100))
另外一個明確的方法:
val txManager = new RawTransactionManager(client,credentials,100,1000 * 15)
val transfer = new Transfer(client,txManager)
transfer.sendFunds(
walletAddress,
amount,
currency.convert)
另外推薦一些之前的教程: