2

Take the transfer function of the DAI contract as example. It allows only two arguments: dst and wad.

This is how the decoded data input looks like on a sample transaction:

Function: transfer(address dst, uint256 wad)

MethodID: 0xa9059cbb
[0]:  0000000000000000000000006262998ced04146fa42253a5c0af90ca02dfd2a3
[1]:  000000000000000000000000000000000000000000000002c3c465ca58ec0000

Is it possible to attach some extra data when calling the transfer function, so that the decoded data input looks as follows:

Function: transfer(address dst, uint256 wad)

MethodID: 0xa9059cbb
[0]:  0000000000000000000000006262998ced04146fa42253a5c0af90ca02dfd2a3
[1]:  000000000000000000000000000000000000000000000002c3c465ca58ec0000
[2]:  000000000000000000000000000000000000000000000000000000000000fede

(obviously without the transaction being reverted or something)

If not possible, is there any other way to attach a message to a transaction that interacts with a contract?

7
  • What exactly are you hoping to achieve by passing another argument? I mean, even if that was possible (and maybe it is somehow, for all I know), it's not like the function contains any code which handles that extra argument. May 21, 2020 at 23:40
  • The idea is to send a message with the transaction
    – viarnes
    May 22, 2020 at 0:07
  • Yeah, I understand the idea, I just don't understand the point in it (sending a message to someone who isn't going to do anything about it). May 22, 2020 at 0:11
  • Not that someone but a third party listening to that kind of transactions
    – viarnes
    May 22, 2020 at 0:20
  • @viarnes If the idea is to sort of hide the communication, you'd be better off using only the available parameters and have a different detection method. May 22, 2020 at 0:59

1 Answer 1

2

It is up to each contract what they will do with extra data in a transaction's input field.

  • It can ignore any extra data
  • It can revert if they receive more thant than they were expecting.

Unfortunatelly there is no standard way to add extra metadata to a transaction to a contract.

If target is an EOA you can add any information you want to input field.


Example to append data to a ERC20 transfer event

const message = '686f6c61'
const data = token.methods.transfer(recipient, amount).encodeABI()

const tx = {
  nonce: '0x00',
  gasPrice: '0x09184e72a000',
  gasLimit: '0xea60',
  to: token.options.address,
  value: '0x00',
  data: data + message
};

const signedTx = new Tx(tx, {'chain':'ropsten'});
signedTx.sign(privateKey);

const serializedTx = signedTx.serialize();
web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'))
.on('receipt', console.log);
9
  • How can a function access arbitrary parameter data? Probably only the fallback function can do that - otherwise the signature wouldn't match? May 22, 2020 at 18:50
  • 2
    @LauriPeltonen It is possible to access raw input data with msg.data, or from assembly with calldataload().
    – Ismael
    May 22, 2020 at 19:35
  • Is there any non-standard way?Also, can you give an example of a contract ignoring the extra data without reverting?
    – viarnes
    May 22, 2020 at 20:37
  • 1
    @viarnes A non-standard is to append to input data, but you have no guarantee that it will work. Most contracts ignore additional data, but a few year ago it was popular to add explicit checks like require(msg.data.length <= xxx).
    – Ismael
    May 22, 2020 at 21:09
  • 1
    @viarnes I've appended a possible example
    – Ismael
    May 23, 2020 at 3:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.