Web3j

無法從 Web3j sendFunds Future 中檢索值

  • December 16, 2017

我一直在嘗試使用 web3j 將資金從一個乙太坊帳戶發送到另一個帳戶,以測試它是否適用於 Android。我正在使用 Infura 雲實例。

首先,看來我需要非同步發送它,因為 Android 要求您這樣做。在下面的程式碼中,我嘗試這樣做 - 但在最後一步,當我嘗試從 Future 獲取時,它失敗了。如果我不嘗試獲取價值,那麼也不例外,但我顯然無法對我想要做的價值做任何事情。

       final String FROM_ADDRESS = "0x6861B070f43842FC16eAD07854eE5D91B9D27C13";
   final String TO_ADDRESS = "0x31B98D14007bDEe637298086988A0bBd31184523";

   //Credentials credentials = obtainCredentials(WALLET_DIRECTORY);

   Callable<TransactionReceipt> task = new Callable<TransactionReceipt>() {
       @Override
       public TransactionReceipt call() throws Exception {
           Web3j web3 = Web3jFactory.build(
                   new HttpService("https://rinkeby.infura.io/SxLC8uFzMPfzwnlXHqx9")
           );
           Log.d(TAG, web3.ethGasPrice().getJsonrpc());

           ClientTransactionManager clientTransactionManager =
                   new ClientTransactionManager(web3, FROM_ADDRESS);
           Log.d(TAG, clientTransactionManager.getFromAddress());

           org.web3j.tx.Transfer tran = new org.web3j.tx.Transfer(web3, clientTransactionManager);
           Log.d(TAG, String.valueOf(tran.getSyncThreshold()));

           RemoteCall<TransactionReceipt> rc = tran.sendFunds(
                   TO_ADDRESS,
                   BigDecimal.valueOf(1.0),
                   Convert.Unit.ETHER
           );
           Log.d(TAG, String.valueOf(rc.toString()));
           return rc.send();
       }
   };
   Future<TransactionReceipt> future = Async.run(task);
   return future.get();

它帶有這個例外:

11-19 12:49:03.418 32442-32442/com.example.graeme.beamitup W/System.err: java.util.concurrent.ExecutionException: org.web3j.protocol.exceptions.ClientConnectionException: Invalid response received: okhttp3.internal.http.RealResponseBody@3c286ab
11-19 12:49:03.418 32442-32442/com.example.graeme.beamitup W/System.err:     at java.util.concurrent.FutureTask.report(FutureTask.java:94)
11-19 12:49:03.419 32442-32442/com.example.graeme.beamitup W/System.err:     at java.util.concurrent.FutureTask.get(FutureTask.java:164)
11-19 12:49:03.419 32442-32442/com.example.graeme.beamitup W/System.err:     at com.example.graeme.beamitup.Transfer.sendTransfer(Transfer.java:183)
11-19 12:49:03.419 32442-32442/com.example.graeme.beamitup W/System.err:     at com.example.graeme.beamitup.MainActivity.onCreate(MainActivity.java:26)
11-19 12:49:03.419 32442-32442/com.example.graeme.beamitup W/System.err:     at android.app.Activity.performCreate(Activity.java:6272)

它指出了來自 HTTP 傳輸的無效響應——但即使不嘗試 Future.get 也不應該發生這種情況嗎?程式碼以任何一種方式執行,對嗎?我做錯了什麼來創建這個錯誤?

1)這條線可能沒有達到你的預期:

Log.d(TAG, String.valueOf(rc.toString()));

rc 有 type RemoteCall<TransactionReceipt>,這意味著它需要被執行。相反,您的程式碼將呼叫轉換為字元串(兩次):一次來自 the toString(),一次來自String.valueOf.

2)你創造了一個未來,然後等待它完成,我知道你知道這是沒有意義的。我放棄了未來,不知道為什麼Android堅持未來。我更簡單的程式碼給出了與您的程式碼相同的結果,因此至少我們知道未來不會引入您報告的問題。

  1. 發送此 JSON-RPC 有效負載後出現錯誤:
{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":1}

ClientTransactionManager.sendTransaction()方法在嘗試執行時終止:

return web3j.ethSendTransaction(transaction)
           .send();

雖然web3j.ethSendTransaction(transaction)看起來工作正常,但連結的send()方法返回一個不成功的響應。我懷疑需要身份驗證,但當然沒有提供憑據,因此交易被拒絕。

我不在 Android 中工作,所以這是我使用的程式碼:

import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.RemoteCall;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.ClientTransactionManager;
import org.web3j.utils.Convert;

import java.math.BigDecimal;

public class SO {
   private static final String FROM_ADDRESS = "0x6861B070f43842FC16eAD07854eE5D91B9D27C13";
   private static final String TO_ADDRESS = "0x31B98D14007bDEe637298086988A0bBd31184523";

   public static void main(String[] args) throws Exception {
       TransactionReceipt value = new SO().test();
       System.out.println(value);
   }

   private TransactionReceipt test() throws Exception {
       //Credentials credentials = obtainCredentials(WALLET_DIRECTORY);

       Web3j web3 = Web3j.build(
           new HttpService("https://rinkeby.infura.io/SxLC8uFzMPfzwnlXHqx9")
       );
       System.out.println("ethGasPrice=" + web3.ethGasPrice().getJsonrpc());

       ClientTransactionManager clientTransactionManager =
           new ClientTransactionManager(web3, FROM_ADDRESS);
       System.out.println("From address=" + clientTransactionManager.getFromAddress());

       org.web3j.tx.Transfer transfer = new org.web3j.tx.Transfer(web3, clientTransactionManager);
       System.out.println("transfer=" + String.valueOf(transfer.getSyncThreshold()));

       RemoteCall<TransactionReceipt> rc = transfer.sendFunds(
           TO_ADDRESS,
           BigDecimal.valueOf(1.0),
           Convert.Unit.ETHER
       );
       TransactionReceipt receipt = rc.send();
       System.out.println("receipt=" + receipt.toString());
       return receipt;
   }
}

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