Web3.js Transactions – Handling Errors When Including Extra Data in web3.eth.sendTransaction()

contract-developmentmetamasksendtransactionweb3js

According to the docs for web3.eth.sendTransaction and the docs for eth_sendTransaction:

The transaction object can contain an optional data parameter which should be a String that consists of:

either an ABI byte string containing the data of the function call on a contract, or in the case of a contract-creation transaction the initialisation code.

I'd like to know the following:

  1. Could I use data to store a String whose value would be anything I like? As in:
const [testAccount] = await window.ethereum.request({ method: "eth_requestAccounts" })
    
const web3 = new Web3(window.ethereum)

if (!testAccount) {
  return
}

await web3.eth.sendTransaction({
  from: testAccount,
  to: testAccount,
  value:  web3.utils.toWei('0.0003'), 
  data: web3.utils.utf8ToHex(JSON.stringify({ a: 1, b: 2 }))
})
  1. If the answer is yes, how big (in bytes) can this string be and if the gas fee increases according to the size of data, can I calculate that in advance ?

Thank you for your help

UPDATE: When I execute the code above, I get the following error:

Error:  Error: TxGasUtil - Trying to call a function on a non-contract address
{
  "originalError": {
    "errorKey": "transactionErrorNoContract",
    "getCodeResponse": "0x"
  }
}

Apparently, you cannot assign any string to data and expect the string to be incorporated in the record of the transaction on the blockchain, out-of-the-box, simply by assigning a value to it.

Question: Do I need to create a custom smart-contract in order to achieve this ?

Best Answer

This is a MetaMask issue.

See comment in their code -

if there's data in the params, but there's no contract code, it's not a valid transaction

This issue was reported here.

FYI your code works perfectly on a non MetaMask env.


You can store a string, but encoded as a hex string. To store 'I love lamp' you need to set data: '0x49206c6f7665206c616d70'.

Use utf8ToHex to convert a string to hex bytes -

web3.utils.utf8ToHex('I have 100€');
> "0x49206861766520313030e282ac"

To know how much gas it costs, use estimateGas, either on a contract's method, or without.

web3.eth.estimateGas({
    to: "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe",
    data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003"
})
.then(console.log);

Re transaction size -

the transaction size limit, at the time of writing, is about 780kB (about 3 million gas).

info taken from this answer.

Related Topic