I want to achieve the following flow:

  • A user clicks a button allowing my contract to spend funds on the user's behalf
  • A user clicks a second button whereupon funds are transferred from the user's wallet to the contract.

From my understanding this needs to be split up into two transactions.

So i thought something like this would work:

Contract code:

function approve(uint amount) public {
  // Calling this function first from remix
  ERC20(Token_address).approve(address(this), amount)

function transferFrom(uint amount) public {
  // Then calling this function from remix
  ERC20(Token_address).transferFrom(msg.sender, address(this), amount)

But it gives me gas estimation failiure inside of remix. I suspect this is because i cannot have the contract call the approve() function. It needs to be called from the user whom is approving the contract to withdraw its funds. How can i achieve this if the user isn't a another smart contract but just a person with a metamask wallet?

  • 1
    The user should call approve, not the contract. Commented Mar 2, 2020 at 15:59
  • ok but if you think about full stack(frontend - metamask and backend) user has to make two metamask transaction. 1) approve method( with metamask) => due to gas consumption then 2) sending balance(with metamas) => also required gas namely this isnt done by just by one metamask click is it true? Commented May 19, 2021 at 18:09
  • Approve was designed to be called from FrontEnd, not from another contract? Commented Jun 9, 2021 at 9:47

2 Answers 2


You're right, your contract should not call the approve method itself, as it would become the msg.sender in the context of the token smart contract, which would cause your contract to self-approve.

You want the user to approve your contract and you can write a script to achieve this. An exemple with web3js 1.2 could be :

var erc20Instance = new web3.eth.Contract(abi,Token_address);

erc20Instance.methods.approve(contractAddress, amount).send({from: userAddress}, 
function(err, transactionHash) {
//some code

with :

  • abi : the abi of the token contract. You can use https://ethereumdev.io/abi-for-erc20-contract-on-ethereum/ for an ERC20.
  • contractAddress : the contract address to approve.
  • amount : the amount to approve. Note that you can "disapprove" the contract by sending a new transaction with an amount of 0, as it will override the previous value.
  • userAddress : the sender's address.

The approve function is used to set allowance for the current sender. If you would call it from your own contract, you would approve spending the tokens for your own contract.

Instead of calling approve through a smart contract, you have to send the transaction directly from the user to the ERC-20 contract, with the address of your own smart contract specified as _sender. To do this, just send a transaction using MetaMask's API.

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.