Send ERC-20 Token Transaction using Web3 js and Private Key

53 Views Asked by At

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

1

There are 1 best solutions below

1
Antonio Da Silva On

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"
    }
    ];