Error: The method eth_sendTransaction does not exist/is not available
Asked Answered
P

4

16

Showing an error while calling solidity contract, which is deployed already in ropsten-infura. I'm using web3(@0.19.1) for calling contract.

Anybody faced the same issue?

Passus answered 14/3, 2019 at 3:52 Comment(1)
what is the error? try to use web3 version 1 series, like [email protected]. the web3 version 0 series is based on callbacks, which most of the time confusing and hard to track errors.Bowl
S
36

I'm guessing that you're connected directly to Infura, which doesn't support eth_sendTransaction. (For it to support that, it would need to know your private key, but it's a shared public node.)

You need to either sign the transaction yourself and then send via eth_sendRawTransaction or use a provider that can hold private keys like MetaMask in the browser.

Sousaphone answered 14/3, 2019 at 13:41 Comment(1)
Are there any providers that support eth_sendTransaction?Writeoff
K
3

This is a sample of smart contract function execution. As we know it's not possible to make a transaction on the Ethereum network without a fee, so you can delegate the fee payment by the contract account:

const rawTx =
{
    nonce: _hex_nonce,
    from: MainAccountAddress,
    to: contractAddress,
    gasPrice: _hex_gasPrice,
    gasLimit: _hex_gasLimit,
    gas: _hex_Gas,
    value: '0x0',
    data: contract.methods.transfer(toAddress, _hex_value).encodeABI()
};

const tx = new Tx(rawTx, { 'chain': 'ropsten' });
tx.sign(privateKey);

var serializedTx = '0x' + tx.serialize().toString('hex');
web3.eth.sendSignedTransaction(serializedTx.toString('hex'), function (err, hash) {
    if (err) {
        reject(err);
    }
    else {
        resolve(hash);
    }
})

Here is the full source to execute the smart contract with delegation by contract main account:

async function TransferERC20Token(toAddress, value) {
    return new Promise(function (resolve, reject) {
        try {
            web3.eth.getBlock("latest", false, (error, result) => {
                var _gasLimit = result.gasLimit;
                let contract = new web3.eth.Contract(contractABI, contractAddress);

                contract.methods.decimals().call().then(function (result) {
                    try {
                        var decimals = result;
                        let amount = parseFloat(value) * Math.pow(10, decimals);
                        web3.eth.getGasPrice(function (error, result) {
                            var _gasPrice = result;
                            try {
                                const Tx = require('ethereumjs-tx').Transaction;
                                const privateKey = Buffer.from(MainAccountPrivateKey, 'hex')

                                var _hex_gasLimit = web3.utils.toHex((_gasLimit + 1000000).toString());
                                var _hex_gasPrice = web3.utils.toHex(_gasPrice.toString());
                                var _hex_value = web3.utils.toHex(amount.toString());
                                var _hex_Gas = web3.utils.toHex('60000');

                                web3.eth.getTransactionCount(MainAccountAddress).then(
                                    nonce => {
                                        var _hex_nonce = web3.utils.toHex(nonce); 

                                        const rawTx =
                                        {
                                            nonce: _hex_nonce,
                                            from: MainAccountAddress,
                                            to: contractAddress,
                                            gasPrice: _hex_gasPrice,
                                            gasLimit: _hex_gasLimit,
                                            gas: _hex_Gas,
                                            value: '0x0',
                                            data: contract.methods.transfer(toAddress, _hex_value).encodeABI()
                                        };

                                        const tx = new Tx(rawTx, { 'chain': 'ropsten' });
                                        tx.sign(privateKey);

                                        var serializedTx = '0x' + tx.serialize().toString('hex');
                                        web3.eth.sendSignedTransaction(serializedTx.toString('hex'), function (err, hash) {
                                            if (err) {
                                                reject(err);
                                            }
                                            else {
                                                resolve(hash);
                                            }
                                        })
                                    });                                
                            } catch (error) {
                                reject(error);
                            }
                        });
                    } catch (error) {
                        reject(error);
                    }
                });
            });
        } catch (error) {
            reject(error);
        }
    })
}
Kepner answered 8/5, 2020 at 21:5 Comment(0)
C
1

I solved this issue by pointing my ganache cli to Infura fork and using local ganache network address in my scripts.

Already pointed by @user94559 it might happen if you are directly connected to Infura.

Corr answered 25/12, 2021 at 10:22 Comment(0)
T
0

You will need to sign the transaction before and that is how I did it using web3 1.0.0.

I used the web3-provider-engine from MetaMask:

getWalletEthTxSubprovider() {
    return new HookedWalletEthTxSubprovider({
        getAccounts: callback => {
            callback(null, [this.web3.eth.defaultAccount]);
        },
        getPrivateKey: (address, callback) => {
            if (address.toLowerCase() === this.web3.eth.defaultAccount.toLowerCase()) {
                return callback(
                    null,
                    Buffer.from(
                        this.web3.eth.accounts.wallet[address].privateKey.replace('0x', ''),
                        'hex'
                    )
                );
            }
            return callback(new Error('not private key supplied for that account'));
        }
    });
}

You can see the full code here

Tectonics answered 27/5, 2019 at 19:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.