Environment:
Geth node Geth/v1.9.0-unstable/windows-amd64/go1.12
Commands used to start the node to mine:
- geth --datadir "." --networkid 101 -verbosity 6 --port 30301 --rpcport 8101 --nodiscover -rpc --rpcapi "db,eth,net,web3,personal" --vmdebug --mine console 2>>"node01.log"
- miner.start(2)
- personal.unlockAccount(eth.accounts[0])
HelloWorld.sol contract:
pragma solidity ^0.5;
contract HelloWorld {
uint256 counter = 5;
function add() public { //increases counter by 1
counter++;
}
function subtract() public { //decreases counter by 1
counter--;
}
function getCounter() public view returns (uint256) {
return counter;
}
}
Java Wrapper Class of the contract
The generated function is:
public RemoteCall<BigInteger> getCounter() {
final Function function = new Function(FUNC_GETCOUNTER,
Arrays.<Type>asList(),
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
return executeRemoteCallSingleValueReturn(function, BigInteger.class);
}
Command used to generate the java class:
web3j truffle generate HelloWorld.json
-o java/classes -p com.web3j
Java interaction with the contract
HelloWorld contract = HelloWorld.load(
contractAddress,
web3j,
credentials,
GAS_PRICE,
GAS_LIMIT);
System.out.println("Valid: " + contract.isValid());
// call method getCounter which retrieves contract data
Function function = new Function(
"getCounter",
Arrays.asList(),
Arrays.asList(new TypeReference<Uint256>() {})
);
String encodedFunction = FunctionEncoder.encode(function);
//unlock account
PersonalUnlockAccount personalUnlockAccount = admin.personalUnlockAccount(account,password).send();
if (personalUnlockAccount.accountUnlocked()) {
System.out.println("Account " + account + " is UNLOCKED.");
}
EthCall ethCall = web3j.ethCall(
Transaction.createEthCallTransaction(credentials.getAddress(), contractAddress, encodedFunction),
DefaultBlockParameterName.LATEST)
.sendAsync().get();
String value = ethCall.getValue();
List<Type> list = FunctionReturnDecoder.decode(value, function.getOutputParameters());
System.out.println(list.size());
Error:
I have tried both with contract deployed with truffle, and with the contract deployed in web3j with .deploy(). In both cases the contract gets deployed and I can check the transaction hash on the geth private note created by me. But in both cases I cannot successfully call the getCounter() function.
The deployed / loaded contract is valid.
I called the method add() with Transaction.createFunctionCallTransaction
and I managed to mine the transaction and obtain the transaction hash.
When I call the getCounter() method in the debugger ethCall.result = "0x"
.
Additional Question:
I have read that this method call should also work because it only retrieves contract data:
contract.getCounter().send();
But it throws the exception:
org.web3j.tx.exceptions.ContractCallException: Empty value (0x) returned from contract
Please help with any hints related to what I might be doing wrong. Thank you.