Web3j Guide – How to Create a RawTransaction for Contract Interaction

contract-invocationprivate-keyraw-transactionweb3j

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?

Best Answer

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)

Related Topic