1

I am working on sending signed transactions using web3, @ethereumjs/tx, and infura. However, I am getting an error "unsigned transactions not supported".

Here my code, credit:

const Web3 = require('web3')
const Tx = require('@ethereumjs/tx').Transaction

const web3 = new Web3(new Web3.providers.HttpProvider('https://rinkeby.infura.io/v3/PROJECT_ID'))

const addressFrom = '0x210490505e07cB9762017288e4729d0f15xxxxxx';
const Key = 'PRIVATE_KEY';
privateKey = Buffer.from(Key, 'hex');
const addressTo = '0x8035f72510907Fe3EE05b4dF439E5D0d977xxxxx';

const txData = {
  gasLimit: web3.utils.toHex(2500000000),
  gasPrice: web3.utils.toHex(10e9), // 10 Gwei
  from: addressFrom,
  to: addressTo,
  //chainId: 4,
  value: web3.utils.toHex(web3.utils.toWei('123', 'wei'))
}

const sendRawTransaction = txData =>
  web3.eth.getTransactionCount(addressFrom).then(txCount => {
    const newNonce = web3.utils.toHex(txCount)
    const transaction = new Tx({ ...txData, nonce: newNonce }, { chain: 'rinkeby' })
    transaction.sign(privateKey)
    const serializedTx = transaction.serialize().toString('hex')
    return web3.eth.sendSignedTransaction('0x' + serializedTx, function(err, hash) {
      if (!err) {
        console.log('Tx Hash:' + hash);
      }else {
        console.log(err);
      }
    });
  })

sendRawTransaction(txData)

Error:

Error: Returned error: transaction could not be decoded: unsigned transactions not supported
at Object.ErrorResponse (/PATH/node_modules/web3-core-helpers/lib/errors.js:28:19)
at /PATH/node_modules/web3-core-requestmanager/lib/index.js:303:36
at XMLHttpRequest.request.onreadystatechange (/PATH/node_modules/web3-providers-http/lib/index.js:98:13)
at XMLHttpRequestEventTarget.dispatchEvent (/PATH/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
at XMLHttpRequest._setReadyState (/PATH/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
at XMLHttpRequest._onHttpResponseEnd (/PATH/node_modules/xhr2-cookies/dist/xml-http-request.js:318:14)
at IncomingMessage.<anonymous> (/PATH/node_modules/xhr2-cookies/dist/xml-http-request.js:289:61)
at IncomingMessage.emit (node:events:381:22)
at endReadableNT (node:internal/streams/readable:1307:12)
at processTicksAndRejections (node:internal/process/task_queues:81:21) {
  data: null
}

Things that I tried:

  • Making data not null
  • Adding 'chainId: 4' in transaction
  • Double checked if my private key is correct.

Thanks.

3 Answers 3

1

There are two issues with your code :

  1. Replace const Tx = require('@ethereumjs/tx').Transaction by const Tx = require('ethereumjs-tx').Transaction (as in the link you provided).

You are currently using the 2.x version of ethereumjs-tx which should not be confused with the 3.x (renamed to @ethereumjs/tx) as there are breaking changes.

  1. Your gas limit is way too high (2500000000)

The block gas limit is limited to 10000000 on the Rinkeby network, your transaction gasLimit must therefore not exceed this quantity. For a simple transfer between two EOAs (with no additional data) you can put 21000 as the gas limit.

7
  • I am still getting the same error even after making both the changes. Commented May 16, 2021 at 17:18
  • what's the version of ethereumjs-tx in package.json ?
    – clement
    Commented May 16, 2021 at 17:23
  • "ethereumjs-tx": "^2.1.2" -- from package.json Commented May 16, 2021 at 17:28
  • Your code works with me with the 2 changes, ethereumjs-tx "^2.1.2" and web3 "^1.2.2". If you still have the issue I have no idea what it could be.
    – clement
    Commented May 16, 2021 at 17:45
  • It works for me as well. I updated my web3. Commented May 16, 2021 at 18:30
0
const Tx = require("ethereumjs-tx").Transaction; // require module for creating transaction object
const Web3 = require("web3"); // require the web3 module to interact with the blockchain and smartcontracts on blockchains
const dotenv = require("dotenv");

// Creating a transaction
// Build the transaction object
// If it is a mainnet, sign the transaction
// Deploy or send seralised Transaction to the blockchain
dotenv.config();
// connecting to blockchain testnet rinkeby
const w3 = new Web3(
  "https://rinkeby.infura.io/v3/aafb8adb2afe49d7bfb057d4bbe3ec8c"
);

// public address to send ether
const addr1 = "0x2f92B9e10D44E9b3554b9a0A9EeB258B7107328c";
const addr2 = "0xbe875509Afaaf0Dc322B8D7db11EFe2d8F3F6bB7";

// private address to sign contract
const private_key = Buffer.from(process.env.Private_Key, "hex"); // addr1 private key

// transaction object
// We are sending 1 ether from our account to another account, with a gasPrice of 10 gwei and Limit of 21000

w3.eth.getTransactionCount(addr1, (err, transactionCount) => {
  const transaction_Object = {
    to: addr2,
    gasPrice: w3.utils.toHex(w3.utils.toWei("10", "gwei")),
    gasLimit: w3.utils.toHex(21000),
    nonce: w3.utils.toHex(transactionCount),
    value: w3.utils.toHex(w3.utils.toWei("0.1", "ether")),
  };

  // Signing the transaction
  const tx = new Tx(transaction_Object, { chain: "rinkeby" }); // creating a new transactrion object to sign
  tx.sign(private_key); // sign the transaction using the private key

  //   Send signed transactiont to the blockchain
  const sTx = tx.serialize();
  const rawTransaction = "0x" + sTx.toString("hex");

  w3.eth.sendSignedTransaction(rawTransaction, (err, hash) => {
    console.log("TxHash:" + hash);
    console.log(err);
  });
});

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Mar 20, 2022 at 13:25
0

Okay I've finally found the answer everybody is looking for!

What's breaking with the previous implementation of ethereumjs-tx is that the signed data is no longer added to the transaction instance. It means it's just present during the .sign line, it is not reachable after.

A fix regarding your implementation, that I've tested, would consist of just compacting the sign and the serialization on one line: const serializedTx = transaction.sign(privateKey).serialize().toString('hex')

Works perfectly with @ethereumjs/tx^3.5.2

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.