I'm writing a smart contract that will do something as long as the user requesting that feature has paid the correct amount. If the amount is in ETH, I can easily do that with a simple require statement like this:

function doSomething() public payable {
    require(msg.value == 1 ether);  // make sure they paid
    // if they paid, proceed with the action

However, if I want to accept other ERC-20 tokens instead of ETH, I am not sure how I would be able to do that inside my contract (i.e. without running my own separate server listening to the blockchain and teasing out individual transactions).

Since all ERC-20 token transfers happen inside the contract for the specific token (and not inside the methods of my smart contracts), how would my contract know or validate that:

  1. The correct amount has been transferred.
  2. The amount was transferred from address A.
  3. The amount was transferred to address B.

Where A is my smart contract, and B is the user.

2 Answers 2


Some ERC20 tokens have the approve and transferFrom functions. In those cases you can have the user approve some tokens to your contract. Then, they can call a function in your contract which will call transferFrom on the token contract.

This requires the user to execute at least two transactions: one to call approve on the token contract, and one to call a function in your contract which in turn will call transferFrom on the token contract.

If the ERC20 token does not have approve and transferFrom, you need a separate server to listen to the blockchain and call your contract.

ERC20 is quite poorly thought out in my opinion, and it was not designed to handle this situation. That's why there are other token standards, such as ERC223: https://github.com/Dexaran/ERC223-token-standard

If ERC223 tokens are transferred to your contract, the token contract will call the tokenFallback function in your contract. This enables the transferal, verification and your contract logic to happen within 1 transaction.

  • So it sounds like there's no real way to do this with one transaction if it's an ERC-20 token (as opposed to the ERC223)? Sounds like the approve and transferFrom technique is the only option.
    – adrianmcli
    Commented Jul 5, 2018 at 8:19
  • @adrianmc If the token contract cannot deliver a callback, you need at least two transactions.
    – Jesbus
    Commented Jul 5, 2018 at 8:45

This can be done in a single transaction. You should use approveAndCall. Using this function the user will approve a number of tokens and call your contract in the same transaction. In this way, your contract will get notified of the token transfer. This of course implies that the contract implements approveAndCall but the odds are that this is implemented because approveAndCall is in the definition fo the standard ERC20 Token

Hope this helps

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.