He estado intentando enviar fondos de una cuenta de ethereum a otra usando web3j para probar que funciona en Android. Estoy usando una instancia en la nube de Infura.
Primero, parece que necesito enviarlo de forma asíncrona porque Android requiere que lo hagas. En el código a continuación, he intentado hacerlo, pero falla en el último paso, cuando intento llegar desde el futuro. Si no trato de obtener el valor, entonces no hay excepción, pero obviamente no puedo hacer nada con el valor que quiero hacer.
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();
Viene con esta excepción:
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)
Señala una respuesta no válida de la transferencia HTTP, pero ¿no debería suceder esto incluso sin probar Future.get? El código se ejecuta de cualquier manera, ¿correcto? ¿Qué he hecho mal para crear este error?
1) Esta línea probablemente no esté haciendo lo que esperas:
Log.d(TAG, String.valueOf(rc.toString()));
rc tiene tipo RemoteCall<TransactionReceipt>
, lo que significa que debe ejecutarse. En cambio, su código convierte la invocación a una Cadena (dos veces): una vez desde toString()
y otra desde String.valueOf
.
2) Creas un futuro, luego esperas a que se complete, y sé que sabes que esto no tiene sentido. Prescindí del futuro, ni idea de por qué Android insiste en un futuro. Mi código más simple da el mismo resultado que su código, por lo que al menos sabemos que el futuro no presentará el problema que informa.
3) El error surge después de enviar esta carga JSON-RPC:
{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":1}
El ClientTransactionManager.sendTransaction()
método muere cuando intenta ejecutar:
return web3j.ethSendTransaction(transaction)
.send();
Aunque web3j.ethSendTransaction(transaction)
parece funcionar bien, el send()
método encadenado devuelve una respuesta fallida. Sospecho que se requiere autenticación, pero, por supuesto, no se proporcionaron credenciales, por lo que se rechazó la transacción.
No trabajo en Android, así que aquí está el código con el que trabajé:
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;
}
}
guerraigual
guerraigual
mike slinn
guerraigual