2

I have this line of code where it registers a transaction in blockchain. And I wanted to know how I can make the nonce different between the transactions?

txhash = careercertificate
            .createCertificate(id, fecha, nombre, rutalumno, instituto, rutinstituto, titulo, totalhash, fechatitulacion, registronumber, codigoV)
            .send().getTransactionHash();
1
  • 1
    I think the nonce is automatically managed for you, each time you call the send() it check the last nonce and increment it by 1, therefore you should give a lot of time between each send() or it will conflict sometimes
    – Majd TL
    Commented Jan 28, 2019 at 19:18

1 Answer 1

7

Under the hood, the Web3J SmartContract Java Wrapper calculates the nonce by getting the number of transactions getTransactionCount for the account (credential).

EthGetTransactionCount ethGetTransactionCount = web3.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.PENDING).send();
BigInteger nonce =  ethGetTransactionCount.getTransactionCount();

If for some reasons, you want to manually set the nonce (because you're sending multiple parallel transactions I guess), it is not an easy task and you gonna have to replicate what web3j is doing behind the scene.

i. Some constants

    final String privateKey = "48c2210576121c68883b2f96ae82cdf5fd845d99f4243b9c44651316accaac97"; // Dummy private key !!!
    final String contractAddress = "0x5e417E6d4e15471912743e1173D5fD3a3617aD9f"; // Smart contract after deployment on Ganache
    final BigInteger gasLimit = new BigInteger("6721975"); // Block gas limit (Ganache)
    final BigInteger gasPrice = new BigInteger("20000000000"); // 20 gwei - Gas Price (Ganache) 

ii. Connect to the node and initiate web3j

// Connect to the node
Web3j web3 = Web3j.build(new HttpService());  // defaults to http://localhost:8545/

iii. Read the private key

// Read Private Key
Credentials credentials = Credentials.create(privateKey)

iv. Calculate the transaction data

A transaction is constituted of several information like from account, to account, value, gasPrice, gasLimit, nonce and data. data in the case of a smart contact represents the encoding of the function, the parameter types and the parameters.

You can calculate data like this:

// Extract the  function from the Smart Contract wrapper generated by web3j cli
final Function function = new Function(
        Counter.FUNC_INCREMENT, 
        Arrays.<Type>asList(), 
        Collections.<TypeReference<?>>emptyList());

// Encode to data
String data = FunctionEncoder.encode(function);

v. Choose a nonce

Based on whatever you want, select a nonce (/!\ must be greater than the nonce of the last transaction on this account)

// Calculate nonce 
(...)
BigInteger nonce =  new BigInteger("101");

vi. Prepare the transaction

// Prepare transaction
RawTransaction rawTransaction = RawTransaction.createTransaction(
        nonce,
        gasPrice,
        gasLimit,
        contractAddress,
        BigInteger.ZERO, // No Value
        data);

vii. Send the transaction

// Transaction manager
RawTransactionManager transactionManager = new RawTransactionManager(web3, credentials);
EthSendTransaction transaction = transactionManager.signAndSend(rawTransaction);

log.debug("transaction hash = {}", transaction.getTransactionHash());

You can find the code here:

0

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.