Insufficient funds for gas * price + value on GSN

My solidity contract is GSNRecipient and also deployed to ropsten network.
when on my client (in vuejs), i connect using
window.web3 = new Web3(new GSNProvider(`https://ropsten.infura.io/v3/{{ID}}`, {useGSN: true}));

I sign the contract method for example like this

         const details = {
           nonce,
           from: coinbase,
           useGSN: true,
           to: ContractAddress,
           gasPrice: window.web3.utils.toHex(window.web3.utils.toWei('50'.toString(), 'gwei')),
           gasLimit: window.web3.utils.toHex(4700000), // Raise the gas limit to a much higher amount
           data: window.MyContract.methods.transfer(this.transfer.to, this.transfer.amount).encodeABI(),
         };
         const transfer = await signAndTransact(window.web3, key, details);

and also my contract address has been funded with 1.0 eth on the Gas Station Network.
but if i use an address that doesnt have ether to send this transaction, it returns
insufficient funds for gas * price + value

2 Likes

Hi @Dike_Jude,

I assume that the transaction isn’t being routed via the GSN.

Is the signAndTransact function from a library?

It may be worth following the Building a GSN-powered DApp documentation to confirm your setup, then create a Vue dapp for that contract and then update to use your contract.

my web3 is connected to the GSN provider as stated here
window.web3 = new Web3(new GSNProvider(https://ropsten.infura.io/v3/{{ID}}, {useGSN: true}))

signAndTransact is a helper function i wrote to sign transactions before sending through infura here

const EthereumTx = require('ethereumjs-tx').Transaction;

    export async function signAndTransact(web3, privateKey, details) {
      const transaction = new EthereumTx(details, { chain: 'ropsten' });
      transaction.sign(Buffer.from(`${privateKey}`, 'hex'));
      const serializedTransaction = transaction.serialize();
      const addr = transaction.from.toString('hex');
      console.log(`Based on your private key, your wallet address is 0x${addr}`);
      const res = await web3.eth.sendSignedTransaction(`0x${serializedTransaction.toString('hex')}`);
      console.log('TxHash', `https://ropsten.etherscan.io/tx/${res.transactionHash}`);
      return res;
    }

I have written my contract according to standards provded on the URL you shared

1 Like

Hi @Dike_Jude,

The problem is that the code is calling helper signAndTransact which calls web3.eth.sendSignedTransaction and bypasses the GSN Provider routing to GSN functionality.

For transactions to be automatically routed through the GSN using the GSN Provider, we need to use send

See the GSN Provider usage documentation: https://docs.openzeppelin.com/gsn-provider/0.1/#usage

Transactions sent to contracts will then be automatically routed through the GSN:

const myContract = new web3.eth.Contract(abi, address);

// Sends the transaction via the GSN
await myContract.methods.myFunction().send({ from });

// Disable GSN for a specific transaction
await myContract.methods.myFunction().send({ from, useGSN: false });