4

I want to sign a transaction that calls a smart contract function and send it to the Rinkeby network.

I found on Web3j documentation the RawTransaction class that supports the methods for the contract creation and for Ethereum exchange, however I'm not able to send a raw transaction that calls a function from the smart contract.

How can I do this? is there a way to use createFunctionCallTransaction from the Transaction class and sign it with my credentials?

0

2 Answers 2

10

Let's take for example the following simple storage contract:

pragma solidity ^0.5.6;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

You can send a transaction to a (already deployed) smart contract with the following code:

// Connect to the node
System.out.println("Connecting to Ethereum ...");
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
System.out.println("Successfuly connected to Ethereum");

// Load an account
String pk = "0xabcdef...1234567890";
Credentials credentials = Credentials.create(pk);

// Contract and functions
String contractAddress = "0x12d8e4546CD10e282083344CD4CA2C55FC3dAbeC";

Function function = new Function("set", // Function name
    Arrays.asList(new Uint(BigInteger.valueOf(20))), // Function input parameters
    Collections.emptyList()); // Function returned parameters

//Encode function values in transaction data format
String txData = FunctionEncoder.encode(function);

// RawTransactionManager use a wallet (credential) to create and sign transaction 
TransactionManager txManager = new RawTransactionManager(web3j, credentials);

// Send transaction
String txHash = txManager.sendTransaction(
    DefaultGasProvider.GAS_PRICE, 
    DefaultGasProvider.GAS_LIMIT, 
    contractAddress, 
    txData, 
    BigInteger.ZERO).getTransactionHash();

// Wait for transaction to be mined
TransactionReceiptProcessor receiptProcessor = new PollingTransactionReceiptProcessor(
    web3j, 
    TransactionManager.DEFAULT_POLLING_FREQUENCY, 
    TransactionManager.DEFAULT_POLLING_ATTEMPTS_PER_TX_HASH);
TransactionReceipt txReceipt = receiptProcessor.waitForTransactionReceipt(txHash);

The code is also available on github

There other and more convenient solutions using a Java Smart contract wrapper (see here)

3
  • I resolved creating a RawTransaction.createTransaction passing as data filed the function encoded. Thanks for your example!
    – Alessandro
    Commented Jul 15, 2019 at 9:47
  • Hey can you explain your approach a little bit? I am also trying to sign my smart contract offline. I am unable to think of what to pass in the "to", "nounce" and "data" fields of the createTransaction method. Commented May 21, 2020 at 8:55
  • To get a return value from a contract call, see @ha-Đang's answer below.
    – devdanke
    Commented Mar 4, 2023 at 16:57
1

Use createFunctionCallTransaction to get a return value from a smart contract call, as shown in an official Web3j example (link below):

querying-the-state-of-a-smart-contract (Web3j v4.8.7)

Then use RawTransactionManager to sign and send the tnx

https://github.com/web3j/web3j/blob/39df8f62c074d64bd88a1154719a49b06644ffb2/core/src/main/java/org/web3j/tx/RawTransactionManager.java#L136

Hope this will help!

1
  • Thanks for linking to the example of a raw contract call that gets a return value.
    – devdanke
    Commented Mar 4, 2023 at 17:21

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.