1

I find lots of examples for making a contract function payable with Ether and requiring specific Ether amounts. But how do I achieve the same with an ERC20 token instead of Ether?

Example: Say I have the following simple contract.

contract SaveMyNumber {

    uint storedNumber;

    function set(uint x) public {
        storedNumber = x;
    }
}

How can I make it require payment of 20 MyERC20Token to allow saving a number?


Bonus question:

Can extensions to ERC20 (like ERC827) help do this better?

3

This can be done with ERC20. but could be tricky

The easiest way is to do it in the original standard ERC20 token contract. Just add this function: (assume as in your question that 20 tokens are required to be able to save the data and that the payment should be done to the owner address)

function payToSave(bytes32 data) public return(bool){
    balance[msg.sender] = balance[msg.sender].sub(20); // be sure to change the number to include the decimal points.
    balance[owner] = balance[owner].add(20);
    register[msg.sender] = data;
    emit Transfer(msg.sender,owner,20)
    return true;
}

but if you are not the owner of the token contract or the token contract is already deployed, you can create another contract with an instance of the token contract. Then use approveAndCall function already in standard ERC20. like this:

Assume the token contract is TheTokenContract (you should add the interface of TheTokencontract in your new contract), then this function will do what you want:

function receiveApproval(address from, uint256 tokens, address token, bytes data) public {
    TheTokenContract instanceContract = TheTokenContract(token);
    instanceContract.transferFrom(from,owner,20);
    register[msg.sender] = data;      
}  

In both examples, the mapping register is just a mapping that saves the data for each user, you can of course change this according to your needs.

Hope this helps.



EDIT after OP comment:

approveAndCall is in the token contract already if the contract is ERC20 compliant.

approveAndCall(address spender, uint tokens, bytes data) public returns (bool success)

Here spender is your contract address. So user will call this function in the token contract and it will approve the value tokens to be moved by your contract to the address that you decide. this function will then call the function receiveApproval that is in your contract.

In short, users will execute approveAndCall in the token contract using the input of 20 tokens and the address of your contract. this function will call your contract on the function receiveApproval as I wrote above. That is all.

  • Thanks for your explanation! Did something go missing? How can I use the approveAndCall function? – Svante Apr 17 '18 at 10:49
  • I just edited the answer. let me know how it goes. – Jaime Apr 17 '18 at 12:18
  • approveAndCall is not part of the ERC20 standard. – Lauri Peltonen Apr 17 '18 at 12:20
  • approveAndCall appears in the ERC20 definition although not in the basic token definition theethereum.wiki/w/index.php/ERC20_Token_Standard – Jaime Apr 17 '18 at 12:24
  • 1
    I check it and you are right it doesn't implement approveAndCall. In this case, you have no other choice than this: the user should use approved in the token contract to allow your contract to claim the 20 tokens and then they should execute in your contract payToSave. Note that the ERC20 implementation described here contains approveAndCall and the description in the ethereum home page of a token example here also have it. Without approveAndCall these tokens usability is really limited. – Jaime Apr 17 '18 at 15:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.