I'm trying to sign a smart contract function with UserA and send the transaction to the Blockchain with UserB, using web3j.

I've tried with web3js and everything worked fine, following the example of openzeppelin

I'd like to do the same with java and web3j, but I'm not able to make it work.

Both following contracts have been wrapped to a java classes, deployed locally (i'm using a dockerized ganache), and I can interact with them: Greeting and MinimalForwarder.

The problems come when I try to execute the function "execute" of the MinimalForwarder. Here's the code:

public TransactionReceipt emitRegistry(Web3j web3j, String signerPrivateKey, String senderPrivateKey, String registryContractAddress, String forwardContractAddress, String addressToSendGreetingsTo) throws Exception {
    final Credentials signerCredentials = Credentials.create(signerPrivateKey);
    final Credentials senderCredentials = Credentials.create(senderPrivateKey);

    BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
    BigInteger gasLimit = DefaultGasProvider.GAS_LIMIT;

    final Function createRegistryfunction = new Function(
            List.of(new Address(160, addressToSendGreetingsTo)),
    byte[] encodedFunction = FunctionEncoder.encode(createRegistryfunction).getBytes(StandardCharsets.UTF_8);

    // Send the signed transaction to the network
    Sign.SignatureData signature = Sign.signMessage(encodedFunction, signerCredentials.getEcKeyPair());
    byte[] signatureInBytes = new byte[65];
    System.arraycopy(signature.getR(), 0, signatureInBytes, 0, 32);
    System.arraycopy(signature.getS(), 0, signatureInBytes, 32, 32);
    System.arraycopy(signature.getV(), 0, signatureInBytes, 64, 1);

    MinimalForwarder minimalForwarder = MinimalForwarder.load(forwardContractAddress, web3j, senderCredentials, new DefaultGasProvider());
    BigInteger nonce = minimalForwarder.getNonce(signerCredentials.getAddress()).send();

    // create forward request
    MinimalForwarder.ForwardRequest forwardRequest = new MinimalForwarder.ForwardRequest(

    return minimalForwarder.execute(forwardRequest, signatureInBytes, gasLimit.add(gasPrice)).send();

I keep receiving the message "MinimalForwarder: signature does not match request". What am I doing wrong?

1 Answer 1


I answer my own question, the implementation can be seen here: https://docs.web3j.io/4.10.0/use_cases/meta_transaction/

Together with the author of the article we've been able to figure it out

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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