1

I have a simple transaction set up to send 100 of my ERC20 token to a certain address. Please see the code below:


if (window.ethereum) {
   
   await window.ethereum.request({ method: "eth_requestAccounts" });
   window.web3 = new Web3(window.ethereum);

let tokenAddress = "my_token_address";
let toAddress = "desitnation_address";
let fromAddress = accountBin;
// Use BigNumber
let decimals = 18;
//let amount = 100;
let minABI = [{"inputs":[{"internalType":"uint256","name":"_initialSupply","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
// Get ERC20 Token contract instance
let contract = new web3.eth.Contract(minABI, tokenAddress);
// calculate ERC20 token amount
//let value = amount.mul(web3.utils.toBN(10).pow(decimals));
// call transfer function
contract.methods.transfer(toAddress, web3.utils.toWei('100')).send({from: fromAddress})

.on('transactionHash', function(hash){


console.log('Payment successful', hash);

My problem is, the transaction is set up correctly but MetaMask displays the transaction as a 'Transfer' when I would like it to display 'Smart Contract Interaction' This way users can't modify the transaction amount via MetaMask.

Thanks.

1 Answer 1

1

The reason why Metamask recognizes the transaction as a Transfer is that the function selector is a common and easily reproduced string. For example, according to solidity-by-example, "transfer(address,uint256)" is encoded into 0xa9059cbb. Metamask and other services like Etherscan must associate all function selectors named 0xa9059cbb is to transfer

enter image description here ^^transfer is recognized by metamask!! enter image description here ^^unusualFunctionSelectorName is just a contract interaction!!

Your solution is to name your function something else. Also, I don't see why users could modify the transaction amount anyways. You might be thinking of the gas. Metamask doesn't support that I think.

3
  • Just a note for your otherwise good answer: renaming the function name makes the contract non-ERC20 compatible. A better alternative (if the user really doesn't want to use the default transfer function) would be to add a new custom function which just forwards the call to the transfer function. Commented Sep 2, 2022 at 6:20
  • @LauriPeltonen I completely forgot about being compliant with the ERC20 standard. Good thinking
    – kev1n
    Commented Sep 2, 2022 at 15:08
  • Hi, Thanks for replying. I've tried your method and it works great but I've run into another issue. Now the value of the transaction is not showing up in the MetaMask transaction. Any ideas? Cheers
    – ozftm
    Commented Sep 6, 2022 at 21:24

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.