2

How do we call payable functions of smart contract using web3j?

UPDATE:

I'm going to change generated smart contract wrapper class manually. Now I have:

    public Future<TransactionReceipt> uploadSignedString(Uint256 verificationId,
                                                     Utf8String signedString) {
    Function function = new Function("uploadSignedString",
            Arrays.<Type>asList(
                    verificationId,
                    signedString
            ),
            Collections.<TypeReference<?>>emptyList());

    return executeTransactionAsync(function);
}

and I'm going to add manually:

public TransactionReceipt uploadSignedStringPayable(Uint256 verificationId,
                                                    Utf8String signedString,
                                                    BigInteger weiValue)
        throws InterruptedException, TransactionTimeoutException, IOException {
    Function function = new Function(
            "uploadSignedString",
            Arrays.<Type>asList(
                    verificationId,
                    signedString
            ),
            Collections.<TypeReference<?>>emptyList());

    return executeTransaction(FunctionEncoder.encode(function), weiValue);
}

and as I see it can be done only as a sync call.

  • Yes, it is possible. Did you try calling a payable function and send required ethers/weis in value? – Sanchit Jul 18 '17 at 6:49
  • It seems to be here with version 2.3.0 of web3j. This included also async Transactions with a weiValue. – Phineas Click Jul 27 '17 at 18:41
  • github.com/web3j/web3j/pull/138 by max taldykin was included in ver. 2.3.0 Thanks, Max! – Viktor Jul 30 '17 at 14:02
2

Update

Since version 2.3.0 web3j generates wrappers with additional argument weiValue for payable functions.

E.g. such code is generated

public Future<TransactionReceipt> pay(Utf8String name, BigInteger weiValue) {
    Function function = new Function("pay", Arrays.<Type>asList(name), Collections.<TypeReference<?>>emptyList());
    return executeTransactionAsync(function, weiValue);
}

for this Solidiy code:

function pay(string name) payable public {}

Old answer

Seems that it is not possible in current version of web3j.

Here is the wrapper code it generates for a payable function without arguments:

public Future<TransactionReceipt> foo() {
    Function function = new Function("foo", Arrays.<Type>asList(), Collections.<TypeReference<?>>emptyList());
    return executeTransactionAsync(function);
}

executeTransactionAsync does not accept ether, but there is synchronous executeTransaction(String data, BigInteger weiValue) which does.

It is possible to call foo along with ether manually:

Function function = new Function("foo", Arrays.<Type>asList(), Collections.<TypeReference<?>>emptyList());
String encodedFunction = FunctionEncoder.encode(function);
Transaction transaction = Transaction.createFunctionCallTransaction(
         from, gasPrice, gasLimit, contractAddress, BigInteger.ONE, encodedFunction);

EthSendTransaction transactionResponse = web3j.ethSendTransaction(transaction).sendAsync().get();

Pull request posted: https://github.com/web3j/web3j/pull/138

  • I tried applying a function with payable and adding a value in wei but it fails and shows value with transaction on etherscan as 0. Do you have any idea why? @max taldykin – Mr.O Sep 1 '18 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.