I found this fantastic code used to generate a smart contract which allows you to send your ERC20 tokens to another address.
A simple overview / explanation of how that works is as following:
We initiate a mapping of all the erc20 coins that the smart contract accepts. Let's say you want to accept only BNB, your contract can do that as there is also a function, allowing the smart contract owner to establish which ERC20 to be accepted. Part of the code:
/**
* @dev list of all supported tokens for transfer
* @param string token symbol
* @param address contract address of token
*/
mapping(bytes32 => address) public tokens;
/**
* @dev add address of token to list of supported tokens using
* token symbol as identifier in mapping
*/
function addNewToken(bytes32 symbol_, address address_) public onlyOwner returns (bool) {
tokens[symbol_] = address_;
return true;
}
/**
* @dev remove address of token we no more support
*/
function removeToken(bytes32 symbol_) public onlyOwner returns (bool) {
require(tokens[symbol_] != 0x0);
delete(tokens[symbol_]);
return true;
}
There are two parts of this smart contract that I don't get. First, what does this code on line 43 do?
ERC20 public ERC20Interface;
From what I found, ERC20 is declared in the openzepelin project which is imported at the beggining. I thought that contracts can be used only with the word 'is' such as (Contract myContract is ERC20).
Assuming that in this circumstance ERC20 comes from the openzepelin project, what does public EERC20Interface
do?
I found ERC20 Interface here but I thought that all smart contracts would have this standard 'interface', so why specifically declaring it?
Second part that I don't get is more complex so I will add /** comments
function transferTokens(bytes32 symbol_, address to_, uint256 amount_) public whenNotPaused {
require(tokens[symbol_] != 0x0);
require(amount_ > 0);
address contract_ = tokens[symbol_];
address from_ = msg.sender;
ERC20Interface = ERC20(contract_); /** what does this line do? Is it initiating a new instance of ERC20? **/
uint256 transactionId = transactions.push(
Transfer({
contract_: contract_,
to_: to_,
amount_: amount_,
failed_: true
})
);
transactionIndexesToSender[from_].push(transactionId - 1);
if(amount_ > ERC20Interface.allowance(from_, address(this))) {
/** what does ERC20Interface.allowance indicate here? is this line checking that the ERC20 sender has enough balance? **/
emit TransferFailed(from_, to_, amount_);
revert();
}
ERC20Interface.transferFrom(from_, to_, amount_);
transactions[transactionId - 1].failed_ = false;
emit TransferSuccessful(from_, to_, amount_);
}