0

After deploying ERC20 contract (MyToken), I transferred all tokens to MyToken contract.

Then I deployed a service contract that has one method called claimWining() which is supposed to transfer tokens to a caller account from MyToken contract.

pragma solidity ^0.5.0;

contract MyToken is Context, ERC20, ERC20Detailed {

    constructor () public ERC20Detailed("DEST", "DST", 18) {
        _mint(_msgSender(), 1000000000 * (10 ** uint256(decimals())));
    }
}

contract Claim {

    MyToken public token;
    address myToken;

    constructor(address _tokenAddress) public {
        token = MyToken(_tokenAddress);
        myToken= _tokenAddress;
    }

    function claimWinning() public {
        // doesn't work
        token.transferFrom(myToken, msg.sender, 100000); 
    }
}

Here I used transferFrom(), but it was not working because I was unable to execute approve() initially.

function approve(address spender, uint256 amount) public returns (bool) {
    _approve(_msgSender(), spender, amount);
    return true;
}

I found that MyToken contract itself should call approve() as msg.sender, but I'm not sure how to do it.

Basically, what I want is platform user calls claimWinning() to get rewarded with ERC20 token. How can users receive tokens from MyToken contract?

1
  • Your conceptual problem is in "transfer tokens to ... from MyToken contract". This contract doesn't have any tokens by itself. – goodvibration Apr 20 '20 at 6:20
0

Your conceptual problem is in this requirement:

transfer tokens to ... from MyToken contract

This contract, despite being the "token manufacturer", does not own any tokens by itself.

Think of it as a bank which serves customers - each customer has an account which holds money, while the bank itself manages all of these accounts without actually owning any of them (or the money that they hold).

When this bank is created, it mints an initial supply:

_mint(_msgSender(), 1000000000 * (10 ** uint256(decimals())));

But as you can see, this initial supply is minted for the bank creator.

In order to mint it for the bank itself, you would need to change it to:

_mint(this, 1000000000 * (10 ** uint256(decimals())));

But since it is not the case, you need to change your requirement to:

transfer tokens to ... from the creator of MyToken contract

6
  • Thanks, I got your point. But what happens 1,000 users need to be rewarded per day? then the creator of MyToken contract would call transfer() from MyToken contract 1,000 times? Is there any way that the users can pay gas fee themselves and receive tokens? – bbusdriver Apr 20 '20 at 7:15
  • 1
    @bbusdriver: Yes. You're looking for an automated airdrop. There is at least one scheme for that which I know of, called merkle-airdrop. – goodvibration Apr 20 '20 at 7:16
  • Could you give me more information on that please? – bbusdriver Apr 20 '20 at 7:17
  • @bbusdriver: I just did. Please see my updated comment. – goodvibration Apr 20 '20 at 7:17
  • 1
    @bbusdriver: Yes, I guess you can do that. – goodvibration Apr 20 '20 at 7:29
1

If the token contract doesn't support functionality to either transfer the tokens or approve transfers then it simply can't transfer tokens. If it owns some tokens they are basically lost / burned.

Typically a token contract only holds a ledger and it's kept as simple as possible. Usually the contract itself doesn't own any tokens directly but there's another contract which handles the tokens - for example a crowdsale contract which initially owns all the tokens and distributes them around when people pay Ether for them. Or then the token contract has a mint functionality which mints tokens when needed, but the contract itself still doesn't ever own its own tokens.

1
  • Thank you, nice explanation. – bbusdriver Apr 20 '20 at 7:15

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.