Skip to content

Instantly share code, notes, and snippets.

@earthchie
Last active July 31, 2024 10:43
Show Gist options
  • Save earthchie/1f12cab7f20bb6cef84a9d9fa1be507b to your computer and use it in GitHub Desktop.
Save earthchie/1f12cab7f20bb6cef84a9d9fa1be507b to your computer and use it in GitHub Desktop.
ethers.js - add text memo to any contract call
/*
// this is what you normally do, right?
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const USDT = new ethers.Contract('0xdAC17F958D2ee523a2206206994597C13D831ec7', [
'function transfer(address recipient, uint256 amount) external returns (bool)'
], signer);
const recipient = '0x...address...';
const amount = 0;
const tx = await USDT.transfer(recipient, ethers.utils.parseUnits(amount.toString(), 6));
await tx.wait();
console.log(tx);
*/
// ok, let turn above code into this instead if you want to add memo to contract call
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const recipient = '0x...address...';
const amount = 0;
const usdtInterface = new ethers.utils.Interface([
'function transfer(address recipient, uint256 amount) external returns (bool)'
]);
const data = usdtInterface.encodeFunctionData('transfer', [
recipient,
ethers.utils.parseUnits(amount.toString())
]);
const memo = 'PUT YOUR MEMO HERE';
const memoBytes = ethers.utils.toUtf8Bytes(memo); // turn string memo into array of bytes
const memoHex = ethers.utils.hexlify(memoBytes); // turn array of bytes into hex data
const trx = await signer.sendTransaction({
to: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT contract address
data: data + memoHex.slice(2) // before append memo, slice 0x prefix first
});
@earthchie
Copy link
Author

earthchie commented Jul 31, 2024

now, to read the data from transaction, do this:

    const provider = new ethers.providers.JsonRpcProvider('...');
    const txHash = '0x...'; // hash of transaction you want to read the memo from
    const tx = await provider.getTransaction(txHash);

    const usdtInterface = new ethers.utils.Interface([
            'function transfer(address recipient, uint256 amount) external returns (bool)'
    ]);
    const decodedData = usdtInterface.decodeFunctionData('transfer', tx.data);

    // reconstruct normal contract call
    const encodedData = usdtInterface.encodeFunctionData('transfer', [
        decodedData.recipient,
        decodedData.amount
    ]);

   // eliminate normal contract call from raw input data
   const memoHex = '0x'+tx.data.replace(encodedData, '');
   
   // turn hex back to string to get the final result
   const memo = ethers.utils.toUtf8String(memoHex);

  console.log(memo);
  

@earthchie
Copy link
Author

btw, for anyone who just want to add memo to native transferring transaction, you can do this: https://gist.github.com/earthchie/a9e42499cfdb3ef3f5db73cf39c6248d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment