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?
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?
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.
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);
}
})
}
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.
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
© 2022 - 2024 — McMap. All rights reserved.