ethereumjs-monorepo icon indicating copy to clipboard operation
ethereumjs-monorepo copied to clipboard

Bytes validation error while transferring ERC20 tokens

Open shikhardb opened this issue 1 year ago • 2 comments

I am trying to send an ERC20 token using ethereumjs, but I am getting a bytes validation error:

Web3ValidatorError: Web3 validator found 1 error[s]:
value "0x2,248,191,131,170,54,167,20,138,49,48,48,48,48,48,48,48,48,48,138,50,48,48,48,48,48,48,48,48,48,131,1,134,160,148,69,107,234,75,230,106,30,153,131,17,135,224,82,187,35,204,80,76,60,225,128,184,68,169,5,156,187,0,0,0,0,0,0,0,0,0,0,0,0,241,238,52,126,93,180,219,205,26,211,198,173,53,86,135,97,41,239,21,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,192,128,160,211,207,218,109,71,160,105,103,166,53,249,71,106,102,227,176,14,254,66,120,191,187,3,169,82,239,111,66,104,57,197,42,160,83,234,223,102,194,94,169,161,93,202,26,67,91,82,179,8,201,43,191,216,203,161,138,112,243,153,167,67,28,98,140,16" at "/0" must pass "bytes" validation

The function to transfer tokens is below:

async function sendToken(toAddress, amount) {
    const txCount = await web3.eth.getTransactionCount(accountAddress);
    const common = new Common({ chain: Chain.Sepolia });

    const maxFeePerGas = web3.utils.toHex(web3.utils.toWei('2', 'gwei'));
    const maxPriorityFeePerGas = web3.utils.toHex(web3.utils.toWei('1', 'gwei')); 

    const txData = {
        "chainId": common.chainId(),
        "nonce": web3.utils.toHex(txCount),
        "maxPriorityFeePerGas": maxPriorityFeePerGas,
        "maxFeePerGas": maxFeePerGas,
        "gasLimit": web3.utils.toHex(100000),
        "to": tokenAddress,
        "value": '0x0',  // Should be '0x0' since we are transferring tokens
        "data": tokenContract.methods.transfer(toAddress, BigInt(amount)).encodeABI()
    };


    const encodedData = tokenContract.methods.transfer(toAddress, BigInt(amount)).encodeABI();
    console.log("Encoded Data: ", encodedData);
    console.log("Transaction Data: ", txData);

    try {
        const tx = FeeMarketEIP1559Transaction.fromTxData(txData, { common: common });
        const signedTx = tx.sign(privateKey);
        const serializedTx = signedTx.serialize();
        const rawTx = '0x' + serializedTx.toString('hex');
        
        console.error('***************');
        console.log('Raw transaction', rawTx);
        console.error('***************');
        
        const receipt = await web3.eth.sendSignedTransaction(rawTx);

        console.log(`Transaction Hash: ${receipt.transactionHash}`);
    } catch (error) {
        console.error("Error creating or sending transaction:", error);
    }
}

Following is the result of logs:

Encoded Data:  0xa9059cbb000000000000000000000000f1ee347e5db4dbcd1ad3c6ad3556876129ef150f0000000000000000000000000000000000000000000000000000000000000004

Transaction Data:  {
  chainId: 11155111n,
  nonce: '0x14',
  maxPriorityFeePerGas: '0x31303030303030303030',
  maxFeePerGas: '0x32303030303030303030',
  gasLimit: '0x186a0',
  to: '0x456Bea4bE66a1E99831187e052BB23cc504C3cE1',
  value: '0x0',
  data: '0xa9059cbb000000000000000000000000f1ee347e5db4dbcd1ad3c6ad3556876129ef150f0000000000000000000000000000000000000000000000000000000000000004'
}

Raw Transaction : 0x2,248,191,131,170,54,167,20,138,49,48,48,48,48,48,48,48,48,48,138,50,48,48,48,48,48,48,48,48,48,131,1,134,160,148,69,107,234,75,230,106,30,153,131,17,135,224,82,187,35,204,80,76,60,225,128,184,68,169,5,156,187,0,0,0,0,0,0,0,0,0,0,0,0,241,238,52,126,93,180,219,205,26,211,198,173,53,86,135,97,41,239,21,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,192,128,160,211,207,218,109,71,160,105,103,166,53,249,71,106,102,227,176,14,254,66,120,191,187,3,169,82,239,111,66,104,57,197,42,160,83,234,223,102,194,94,169,161,93,202,26,67,91,82,179,8,201,43,191,216,203,161,138,112,243,153,167,67,28,98,140,16

The error comes when it reaches web3.eth.sendSignedTransaction(rawTx);

shikhardb avatar Apr 20 '24 00:04 shikhardb

What version of @ethereumjs/tx are you using? The one thing that jumps out to me is you're calling toString on the result of signedTx.serialize. Unless you're on an older version of our transaction library where serialize returns a Buffer, that's not going to produce a valid hex value since our serialize function returns a Uint8Array and that doesn't have a toString('hex') function on the prototype. That seems to be represented in the Raw Transaction snippet. If you're using the current versions of our libraries, you can just import bytesToHex from our @ethereumjs/util library and then do something like:

  const rawTx = bytesToHex(serializedTx)
  const receipt = await web3.eth.sendSignedTransaction(rawTx);
  console.log(`Transaction Hash: ${receipt.transactionHash}`);

and that should solve your issue.

If not, please provide a complete example repo that reproduces the issue and I can look further at it.

acolytec3 avatar Apr 21 '24 01:04 acolytec3

@shikhardb were you able to solve your issue?

acolytec3 avatar Apr 24 '24 01:04 acolytec3

Closing due to inactivity

acolytec3 avatar May 08 '24 21:05 acolytec3