Bytes validation error while transferring ERC20 tokens
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);
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.
@shikhardb were you able to solve your issue?
Closing due to inactivity