node.jsethereumweb3jsbinance-smart-chain

Transaction problem with Web3 BEP20 in Node JS


So I'm trying to send a transaction on BSC (testnet) with nodejs web3 (bep-20). After sending via the contract with web3 I only get a TX hash as a response and no receipt or anything like that. When I search for the transaction on the blockchain it doesn't exist. But then when trying to send another transaction and I get an error INTERNAL_ERROR: could not replace existing tx. It works if I change the nonce but then again I only get the TX has h returned which doesn't exist. Also, no funds get spent from my address.

My code:

const contract = new web3.eth.Contract(abiJson, contract_address, { gasPrice: "51067" });

await contract.methods.transfer(receiver_address, 10000000).send({
      from: sender_address,
      gas: 21596,
      nonce: 0,
    })
    .on("transactionHash", function (hash) {
      console.log(hash);
    })
    .on("confirmation", function (confirmationNumber, receipt) {
      console.log(confirmationNumber, receipt);
    })
    .on("receipt", function (receipt) {
      // receipt example
      console.log(receipt);
    })
    .on("error", function (error, receipt) {
      console.log(error, receipt);
    })

Returned TX hash example:

0x0ac1c9e3ad108068f953299c82343057d2e739fab9801e897b25d53170fe3ff0

UPDATE

when I use web3.eth.getTransaction(txHash); I get the following:

{
  blockHash: null,
  blockNumber: null,
  from: '0x5de622df348974877Cf7108785f67e09b97785Fc',
  gas: 21596,
  gasPrice: '51067',
  hash: '0x0ac1c9e3ad108068f953299c82343057d2e739fab9801e897b25d53170fe3ff0',  input: '0xa9059cbb000000000000000000000000ff3b0833aab74477d5efa1665632709cc8e2e0f800000000000000000000000000000000000000000000000000000000000186a0',    
  nonce: 4,
  to: '0x337610d27c682E347C9cD60BD4b3b107C9d34dDd',
  transactionIndex: null,
  value: '0',
  type: 0,
  v: '0xe5',
  r: '0x2a0c5365fff32a2314ab1aee0847aa7202b5cdd8f5e070df162e47b7e9ed65a5',   
  s: '0x4415513033acb12a484498252b8247d8f33bbb80d5093f77df4d2c515744dde7'    
}

Still, I don't understand why the TX isn't going live.


Solution

  • From the looks of it, you created the tx instance but you did not sign it and send it. This is an example of a complete code to do what you intended.

    const Web3 = require("web3");
    const web3 = (new Web3(new Web3.providers.HttpProvider(`rpc address`)))
    const Common = require('ethereumjs-common');
    const Tx = require('ethereumjs-tx')
    
    async function main(){
    const busd = "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56";
    const abi = "put contract abi here"
    
    const contract = new web3.eth.Contract(abi, busd)
    let sender = "sender wallet"
    let receiver = "receiver wallet"
    let senderkey = Buffer.from("sender private key", "hex")
    
    let data = await contract.methods.transfer(receiver, web3.utils.toHex(1000000000000000000)) //change this value to change amount to send according to decimals
    let nonce = await web3.eth.getTransactionCount(sender) //to get nonce of sender address
    
    let chain = {
    
        "name": "bnb",
        "networkId": 56,
        "chainId": 56
    }
    
    let rawTransaction = {
        "from": sender,
        "gasPrice": web3.utils.toHex(parseInt(Math.pow(10,9) * 5)), //5 gwei
        "gasLimit": web3.utils.toHex(500000), //500,000 gas limit
        "to": busd, //interacting with busd contract
        "data": data.encodeABI(), //our transfer data from contract instance
        "nonce":web3.utils.toHex(nonce)
    };
    
    const common1 = Common.default.forCustomChain(
        'mainnet', chain,
        'petersburg'
    ) // declaring that our tx is on a custom chain, bsc chain
    
    let transaction = new Tx.Transaction(rawTransaction, {
        common: common1
    }); //creating the transaction
    
    transaction.sign(senderkey); //signing the transaction with private key
    
    let result = await web3.eth.sendSignedTransaction(`0x${transaction.serialize().toString('hex')}`) //sending the signed transaction
    console.log(`Txstatus: ${result.status}`) //return true/false
    console.log(`Txhash: ${result.transactionHash}`) //return transaction hash
    }
    main()