Web3js – How to Use SendTransaction to Send ERC20 Tokens with Metamask

erc-20metamaskweb3js

I have a custom ERC20 token and I want to enable metamask support. By this I mean:

1) The user clicks a "Pay using metamask" button

2) The Metamask payment window pops up and with "Pay 100 ABC tokens" (not ETH), with the usual gas price, etc.

How would I do this? I wrote my method halfway, but realized it would only work for ETH.

My ethereum.js file:

const sendTransaction = ({ cost, to, gasPrice }) =>
  new Promise((resolve, reject) => {
    if (window.ethereum) {
      const ethereum = window.ethereum;
      const Web3 = window.Web3;
      const web3 = new Web3(ethereum);
      try {
        ethereum.enable().then(accounts => {
          const from = accounts[0];
          web3.eth.sendTransaction(
            {
              from,
              to,
              gasPrice,
              value: "1000000000000000000"
            },
            (err, res) => {
              err ? reject(err) : resolve();
            }
          );
        });
      } catch (error) {
        reject(error);
      }
    } else if (window.web3) {
      const Web3 = window.Web3;
      const web3 = new Web3(window.web3.currentProvider);
      web3.eth.getAccounts().then(accounts => {
        const from = accounts[0];

        web3.eth.sendTransaction(
          {
            to,
            from,
            value: "1000000000000000000"
          },
          (err, res) => {
            err ? reject(err) : resolve();
          }
        );
      });
    } else {
      console.log(
        "Non-Ethereum browser detected. You should consider trying MetaMask!"
      );
    }
  });

export default {
  sendTransaction
};

Best Answer

Donot use value field if you dont want to send ether. Value field is only used for ether. Now you have to construct the data for the transaction. if using web3@0.2.0 then you can do

contractData = contractInstance.transfer.getData(address, amount)
//contractData = '0x12345643213456000000000023434234'

this will give you the data for the transaction. After that the transaction object will look like this

{
    nonce: nonceHex,
    gasPrice: gasPriceHex,
    gasLimit: gasLimitHex,
    data: contractData,
    to: contractAddress,
    chainId: 1(main net), 2(expanse), 4(rinkeby)
    from: fromAddress
}

But it wont say "Pay 100 ABC tokens", but there will be a popup for confirmation to send transaction