Web3JS – How to Make Smart Contract Calls Using INFURA and NodeJS

contract-debugginginfuraraw-transactionweb3js

I can not understand how I can prepare the transaction to be signed. Because INFURA does not support eth_sendTransaction but only eth_sendRawTransaction (INFURA API which then requires you to prepare a signed transaction) I have no idea how I can do that.

This is the code that I use to try send transaction, that it fails:

PrintProofOfWork.methods.printRequested(web3.utils.keccak256(gcodeHash)).send('0x' + serializedTransaction.toString('hex'))
        .then((result) => {
            log(`result of the invokation: ${result})`.red);
        }).catch((err) => {
        log(`error occurred: ${err})`.red);
    });

The error I get is:

error occurred: Error: Node error: {"code":-32601,"message":"The method eth_sendTransaction does not exist/is not available"})

Can anyone kindly show me how I can prepare a transaction that invokes the method of a Smart Contract with parameters, sign it and then send it with INFURA?

Best Answer

First of all INFURA does not allows to send unsigned transactions, so you have to sign them firstly and then pass them to INFURA.

To do this, you have to:

  1. prepare the transaction
  2. sign it
  3. send it (using INFURA)

Please check INFURA documentation.

There is an example below:

const Web3 = require('web3')
const Tx = require('ethereumjs-tx')

// connect to Infura node
const web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/INFURA_KEY'))

// the address that will send the test transaction
const addressFrom = '0x1889EF49cDBaad420EB4D6f04066CA4093088Bbd'
const privKey = 'PRIVATE_KEY'

// the destination address
const addressTo = '0x1463500476a3ADDa33ef1dF530063fE126203186'

// Signs the given transaction data and sends it. Abstracts some of the details 
// of buffering and serializing the transaction for web3.
function sendSigned(txData, cb) {
  const privateKey = new Buffer(config.privKey, 'hex')
  const transaction = new Tx(txData)
  transaction.sign(privateKey)
  const serializedTx = transaction.serialize().toString('hex')
  web3.eth.sendSignedTransaction('0x' + serializedTx, cb)
}

// get the number of transactions sent so far so we can create a fresh nonce
web3.eth.getTransactionCount(addressFrom).then(txCount => {

  // construct the transaction data
  const txData = {
    nonce: web3.utils.toHex(txCount),
    gasLimit: web3.utils.toHex(25000),
    gasPrice: web3.utils.toHex(10e9), // 10 Gwei
    to: addressTo,
    from: addressFrom,
    value: web3.utils.toHex(web3.utils.toWei(123, 'wei'))
  }

  // fire away!
  sendSigned(txData, function(err, result) {
    if (err) return console.log('error', err)
    console.log('sent', result)
  })

})
Related Topic