I am trying to send a custom ERC-20 token transaction using web3.js and using the sender private key to sign the transaction. Although in my current code i am getting the following error:
Transaction has been reverted by the EVM
Here I call the function sendToken(Sender Public Key, Sender Secret Key, Receiver Public Key, Amount of Tokens to Send):
sendToken("0x0000_SENDER_PUBLIC_KEY", "0x0000_SENDER_SECRET_KEY", "0x0000_RECIPIENT_PUBLIC_KEY", "0.005");
Here is the function i am using (Min ABI mention bellow):
async function sendToken(tokenHolder, walletSecret, toAddress, amount) {
const nonce = await web3.eth.getTransactionCount(tokenHolder);
const gasPrice = await web3.eth.getGasPrice();
const gasLimit = 200000;
const params = {
from: tokenHolder,
to: toAddress,
nonce: web3.utils.toHex(nonce),
data: minABI,
value: web3.utils.toHex(web3.utils.toWei(amount, 'ether')),
gasPrice: web3.utils.toHex(gasPrice),
gasLimit: web3.utils.toHex(gasLimit),
};
const signedTx = await web3.eth.accounts.signTransaction(params, walletSecret);
try {
web3.eth.sendSignedTransaction(signedTx.rawTransaction)
.on('transactionHash', function(hash){
console.log("txHash", hash);
})
.on('receipt', function(receipt){
console.log("receipt", receipt)
})
.on('confirmation', function(confirmationNumber, receipt){
console.log("confirmationNumber",confirmationNumber,"receipt",receipt)
})
.on('error', console.error);
} catch(error) {
console.log(error);
}
}
Minimum ABI data I am using (it works well for other functions like, get account erc-20 tokens Balance):
// The minimum ABI to get ERC20 Token balance
let minABI = [
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "balance",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
];
// Define the ERC-20 token contract
window.web3 = web3;
window.minABI = minABI;
}
What I am doing wrong? Cheers
Ok i found the issue. It was on the previous params data. In "to" and "from". Also the contract ABI was incorrect.
The full working code:
<script>
"use strict"
async function sendToken(tokenHolder, HolderSecretKey, toAddress, amount) {
const gasPrice = await web3.eth.getGasPrice();
const gasLimit = 200000;
const walletSecret = HolderSecretKey;
// Creating a signing account from a private key
const signer = web3.eth.accounts.privateKeyToAccount(walletSecret);
web3.eth.accounts.wallet.add(signer);
const nedTokenContractAddress = "0x00MY_ERC20_CONTRACTADRESS";
const web3contract = new web3.eth.Contract(transferABI, nedTokenContractAddress, { from: signer.address } )
const amountInWei = web3.utils.toWei(amount, "ether");
const params = {
from: tokenHolder,
to: nedTokenContractAddress,
nonce: await web3.eth.getTransactionCount(tokenHolder),
value: '0x00',
data: web3contract.methods.transfer(toAddress, amountInWei).encodeABI(),
gasPrice: web3.utils.toHex(gasPrice),
gasLimit: web3.utils.toHex(gasLimit),
};
const signedTx = await web3.eth.accounts.signTransaction(params, walletSecret);
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction)
.once("transactionHash", (txhash) => {
console.log(`Mining transaction ...`);
console.log(`https://polygonscan.com/tx/${txhash}`);
alert(txhash);
});
// The transaction is now on chain!
console.log(`Mined in block ${receipt.blockNumber}`);
}
</script>
And for the ABI use the following:
// The ABI to send ERC20 Token transfers
let transferABI = [
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"type": "function"
}
];