The answers given so far do not address the question. The Idea is that you create a smart contract. This smart contract can receive ether or other tokens. The question is, how can be checked how many tokens of a particular 'type' were received?
In general, a token (ERC20 like) is just a balance. When you see tokens in your wallet, this is the wallet accessing the balance in the contract (because the contract for that token has issued an event indicating a change in the balance). This mean, you do not really receive the tokens in your wallet.
Now, assume you created the token_1 using a contract. Another contract has created the token_2. If I send the token_2 to your contract address, what happens is that the balance of the contract that created Token_2 updates the balance and adds your contract's address to the bookkeeping. Your contract will not react to this, and this is why usually sending tokens to wrong contract's address results in lost funds.
You will need to listen to the events of the other contract to know who and how much of a particular token has been sent to you, but this can not be done in the smart contract, you will need an off-chain code that read the events.
I hope this help.
By executing approve(someAccount, someAmount)
in a contract function, you are approving someAccount
to transfer up to someAmount
from that contract.
Hence, by executing approve(address(this), someAmount)
in a contract function, you are approving that contract to transfer tokens from itself!
Obviously, it doesn't allow you to then execute transferFrom(someOtherAccount, ..., ...)
, because the contract is not approved to transfer tokens from someOtherAccount
.
And you wouldn't want it to allow that anyway, because if it did, then the entire ERC20 model would be worthless as a financial system, as you could approve and transfer from any account you'd want to.
In short, you need to call approve
outside of this contract, using the account which you want this contract to transfer tokens from.
Best Answer
Transferring tokens is basically to change the entries in a variable in the token contract. This means that there is nothing actually moved.
Assume a user with address A, a token contract B and another contract (yours) with address C.
If A decides to sent x tokens to your contract C what happens is that a transaction is sent to B. B has a mapping with the balances of all the users, and subtract x tokens from the balance of A and adds x tokens to the balance of C. This means that C never get to know that a transfer of x tokens was sent to it.
This is why you can't forbid tokens to be sent to your contract because transferring tokens to your contract do not involve your contract at all.
However, there is an option. ERC20 standard implements a function
approveAndCall
which allows users (for instance A) to approve your contract (C) to move x amount of tokens from their balance in (B). This function will actually call your contract and you will see the address of the token. If the call is from your token contract you can just transfer from the x tokens to you contract usingtransferFrom
and execute your code. If the call is from another contract you just revert.For the rest, if someone does normal transactions to your contract, you do not need to worry, your contract will will never know.
Hope this helps.