Web3j: Java wrapper generator does not properly handle payable functions

Created on 22 Sep 2020  路  4Comments  路  Source: web3j/web3j

Java wrapper generator for smart contract does not properly handle payable functions

There is no overload generated to send Ether into the smart contract function call, even though the
contract function is marked payable.

Steps To Reproduce

Consider this solidity function

    function sendEthWithContract(address payable _recipient) external payable {
        require(msg.value > 0);
        _recipient.transfer(msg.value);
    }

Compile the contract and generate the Java wrapper. It generates

    public RemoteFunctionCall<TransactionReceipt> sendEthWithContract(String _recipient) {
        final org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(
                FUNC_SENDETHWITHCONTRACT, 
                Arrays.<Type>asList(new org.web3j.abi.datatypes.Address(160, _recipient)), 
                Collections.<TypeReference<?>>emptyList());
        return executeRemoteCallTransaction(function);
    }

This is wrong as you have to generate an overload that passes Eth all the way down to the execution of the
transaction. This is clear as the function is marked as payable.

Instead it forwards the execution of the transaction to

    protected TransactionReceipt executeTransaction(Function function)
            throws IOException, TransactionException {
        return executeTransaction(function, BigInteger.ZERO);
    }

This is clearly wrong.

Environment

  • Web3j version. core 4.6.0, codgen 4.5.18,
  • Java 8
  • Operating System Mac OS X Catalina
bug

Most helpful comment

Known issue

the wrapper generator is expecting "payable: true" rather than "stateMutability: payable" to correctly generate wrapper functions for payable function

in the meantime here is an example of a function which will take msg.value and encode it correctly

    public RemoteFunctionCall<TransactionReceipt> newGreeting(String _greeting, BigInteger weiValue) {
        final Function function = new Function(
                FUNC_NEWGREETING, 
                Arrays.<Type>asList(new org.web3j.abi.datatypes.Utf8String(_greeting)), 
                Collections.<TypeReference<?>>emptyList());
        return executeRemoteCallTransaction(function, weiValue);
    }

you should just be able to add the weiValue as a function parameter
and then add it to the executeRemoteCallTransaction parameters

All 4 comments

Have the same issue;

Known issue

the wrapper generator is expecting "payable: true" rather than "stateMutability: payable" to correctly generate wrapper functions for payable function

in the meantime here is an example of a function which will take msg.value and encode it correctly

    public RemoteFunctionCall<TransactionReceipt> newGreeting(String _greeting, BigInteger weiValue) {
        final Function function = new Function(
                FUNC_NEWGREETING, 
                Arrays.<Type>asList(new org.web3j.abi.datatypes.Utf8String(_greeting)), 
                Collections.<TypeReference<?>>emptyList());
        return executeRemoteCallTransaction(function, weiValue);
    }

you should just be able to add the weiValue as a function parameter
and then add it to the executeRemoteCallTransaction parameters

Was this page helpful?
0 / 5 - 0 ratings