I am attemping to send a transaction to the Ethereum blockchain using the Web3j library, I get an error that I must send it with Async. When I send it with Async I get an error that the function does not exist. I am using Android Studio, Java, and the Web3j library.
When calling the executeTransactionAsync
method, part of web3.abi.datatypes.Function
, I get an error saying the method can not be found. I figured out this means that the method executeTransactionAsync
does not exist in the Web3j library. However, the Web3j documentation says to use that method. I am using the latest version of Web3j which is 3.1.1.
If I remove the Async so the method is executeTransaction
, I get an error that the Transaction needs to be sent through Async.
Is there a way I could send this transaction with Realm or something else? Or maybe I am using Web3j wrong and I need to use it another way?
The code sending the transaction:
public TransactionReceipt approve() throws IOException, TransactionException {
Function function = new Function("approve", Arrays.<Type>asList(), Collections.<TypeReference<?>>emptyList());
return executeTransactionAsync (function);
}
You need to use an executeTransaction
wrapped in a RemoteCall
.
Function function = new Function(...);
RemoteCall<TransactionReceipt> remoteCall = new RemoteCall(() -> {
//call to executeTransaction
});
TransactionReceipt receipt = remoteCall.send();
You can make life easier for yourself by using web3j's code generation tools which creates simple wrappers for your smart contract. See this section of the web3j documentation on how to generate your code. The generated class handles the remote calls (and local calls for constant
functions). Your client code becomes something like:
Web3j web3j = Web3j.build(new HttpService());
Credentials credentials = Credentials.create(<YOUR_PRIVATE_KEY>);
SimpleContract contract = SimpleContract.load(<CONTRACT_ADDRESS>, web3j, credentials, BigInteger.valueOf(<GAS_PRICE>), BigInteger.valueOf(<GAS_LIMIT));
RemoteCall<TransactionReceipt> remoteCall = contract.setValue(BigInteger.valueOf(5)); // Call to smart contract setValue(5)
TransactionReceipt receipt = remoteCall.send();
Edit to add code generation example
$ solc --version
solc, the solidity compiler commandline interface
Version: 0.4.19+commit.c4cbbb05.Windows.msvc
$ java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
$ solc contracts/SimpleContract.sol --bin --abi --optimize -o build/
$ web3j.bat solidity generate build/SimpleContract.bin build/SimpleContract.abi -o ./src -p mypackage
_ _____ _ _
| | |____ (_) (_)
__ _____| |__ / /_ _ ___
\ \ /\ / / _ \ '_ \ \ \ | | | / _ \
\ V V / __/ |_) |.___/ / | _ | || (_) |
\_/\_/ \___|_.__/ \____/| |(_)|_| \___/
_/ |
|__/
Generating mypackage.SimpleContract ... File written to .\src
Note - I'm running on Windows with Cygwin. Hence, the web3j.bat
usage.