this https://theethereum.wiki/w/index.php/ERC20_Token_Standard eth wiki describes erc20 standard as a set of functions and attributes a token needs to have implemented. some of them are pretty self explanatory like
function transfer(address to, uint tokens) public returns (bool success);
which takes coins from your wallet and transfers it to somebody elses.
But on the other hand
function approve(address spender, uint tokens) public returns (bool success);
or
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
How am I supposed to know what is the logic behind these methods? are there any extra docs describing it? and last but not least: what are upsides of tokens being ERC20 compliant?
ERC20 standard contains a set of functions that were proposed EIP-20 which were reviewed and voted on by community. As per abstract states the following:
This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party.
See here for more some analogous examples on what approve and allowance do, but basically these are functions that allow an account owner to approve moving a fixed amount of tokens from their account to another account. approve allows you to authorize an address to move a fixed amount, while allowance simply returns this amount.
Looking at the EIP and ERC20 documentation can be a bit daunting at once, but one you start playing with the functions it makes a lot more sense. For quickest way to start testing I'd suggest using Ethereum's remix.
If you think the documentation on that wiki is not enough, you can look at the original EIP and look at all of the discussions involved that led to the final version, along with links to additional documentation and code examples to further explain the intention of each function. Note that all of the ERCs have a corresponding EIP, so you can refer to those for all of the other token standards.
what are upsides of tokens being ERC20 compliant?
The upside is that others will know how to work with your token.
Related
I have some functions that I'm trying to save gas on.
onlyOwner modifier is self explanatory.
This is related to a previous question that I had, where I noticed that address(this) is different from msg.sender in a given contract. Upon further reading I get the impression that address(this) is a hash of msg.sender, but the two are not considered the same. Is this correct?
Since address(this) is related to the owner address, is the owner address (msg.sender, set within the contract's constructor) considered different enough from the contract address address(this) so as to be considered external visibility?
// can the owner (set in the constructor) call this function once it is deployed on the blockchain?
function setXYZ(address _address) external onlyOwner returns (bool success) {
XYZ[_address] = 4;
return true;
}
Seems to work when I test it within my IDE, but I don't know if there is a difference in implementations between my test environment and the blockchain environment.
Upon further reading I get the impression that address(this) is a hash of msg.sender, but the two are not considered the same. Is this correct?
address(this) returns address of the currently executed contract. When a contract is deployed, it's assigned an address which is determined by hash of "the deployer address combined with other data". Once the contract address is assigned, it never changes.
On the other hand, msg.sender reflects address of whoever is currently executing the contract. So if Alice executes a function, msg.sender is her address - and if Bob executes the same function, msg.sender reflects his address.
As the OpenZeppelin Ownable code shows, the deployer address (msg.sender in constructor) becomes the initial owner.
And the onlyOwner modifier validates whether the current msg.sender is the owner. If they match - all good. If the currrent msg.sender is different from the owner, it reverts the transaction.
Seems to work when I test it within my IDE, but I don't know if there is a difference in implementations between my test environment and the blockchain environment.
This code will work the same on all EVM networks.
There are few very small differences between the EVM implementation in emulators and live networks (as well as between different live networks). But they mostly affect low-level features such as ordering of transactions in a block or gas usage optimizations.
I have an Eth contract, called the controller, which is used to:
Generate new eth deposit addresses, one for each user, which is
an eth contract as well.
Sweep these deposit contracts when a user deposits eth or erc20 token to them. The funds end up in another central eth account.
A number of erc20 tokens seem to work perfectly, but USDT deposit transactions get reverted: https://etherscan.io/address/0x3cd5a0dc36a8f22011193f2a03910aa8260e64db
Without the original source code for these contracts (although I have the JSON ABI), it is hard to say:
Why it fails for USDT.
If these actually can support USDT, or what it would involve to do so.
If anyone can point in the right direction, it will be appreciated!
Controller contract:
0xEb818C6a48cCd60A8078aaa20997cC3CB2538C9E
Another contract involved linked to controller, called defaultSweeper:
0x8e7ABAF1316A0edB985e494F572Fdf148e8a7E93
EDIT:
It seems that USDT contract is missing some erc20 methods. Like transfer See: https://erc20-verifier.openzeppelin.com/ Why is this?
Tether contract was deployed before the ERC20 standard was finalized. Some functions don't follow the specs, for example transfer should return a boolean and it doesn't.
Recent versions of solc will check the returned data size is correct (since 0.5 I think).
My guess is that your contract was compiled with a recent version of solidity and it uses the standard ERC20 interface. And it fails because Tether returns nothing and it is expecting a bool value.
There isn't much you can do. Either Tether should upgrade its contract or the controller contract has to be modified to do not check the contract size. See SafeERC20 from OpenZepplin, they implemented a wrapper around ERC20 that allows interfacing with tokens that are not compliant with the standard.
I do not have much experience with Solidity programming. I want to create a smart contract for a new digital asset, say Cryptodoggies. I want to know if there is a way to prevent users from being able to resell/transfer their cryptodoggies.
You could have a variable (boolean I think would be more suitable) on your contract and use it in an access modifier for the transfer function so that the transfer function would require for this variable to be true. Then by making this variable false (by a function accessible only to you) you can stop users from transferring coins. Of course, this modifier would have to be used for every function that enables users to transfer tokens.
It would be something like that pausable ERC-20 from openzeppelin. You can find it here.
Is it possible to get a list of token holders for a given ERC20 token from within another solidity contract?
Since "balances" are stored in a mapping in most ERC20 contracts, I do not think it is possible, since you can't get a list of keys for a mapping in solidity.
Is there anything I missed? Or is this just impossible?
Thanks!
It is not possible to get a list of ERC20 token holders directly from a contract.
You are correct in that you cannot do this because you cannot get a list of keys for a mapping in Solidity, therefore it is impossible without external intervention.
With that said, there are many people who need this functionality and perform tasks to achieve this. The biggest example I can think of is airdropping tokens to various accounts based on their holdings of another token. The way that most people do this is to read all of the token holders from the blockchain and store it in a local database. From there, they will implement a gas-efficient function that takes in the addresses as a parameter and performs actions on them that way.
It is not possible to accomplish what you desire using only the blockchain, but using a combination of on-chain/off-chain logic can achieve your goals.
It maybe possible.
If you make a function that can pick sender and receiver when transfer function is called, it's possible.
mapping(address => bool) _holderList;
function transferFrom(address from, address to, uint256 amount) {
checkHolderList(from);
checkHolderList(to);
_transfer(from, to, amount);
}
function checkHolderList(address _address) {
require(balanceOf(_address) > 0, "this address can't be holder");
require(_holderList[address] != true, "this address is already in holder list");
_holderList[_address] = true;
}
I want to create a smart contract which people can transfer tokens without ether in their wallet.
Suppose A want to transfer ERC20 tokens to B, but he does not have ether in his wallet.
Does third party C can send the transaction for A and therefore pay the gas? Is it possible to create a function in the contract for this usgae?
I have searched online for a soloution and could not find one.
This is a key issue of Ethereum dApp development, but also of tokens. Here is a very old thread on Ethereum Stack Exchange, and also this one.
There are 2 options with their pros and cons:
Use signatures
Every function in your smart contract must have signature parameter.
People who want to interact with the smart contract must sign the function parameters with their account's private key and send it to the smart contract owner (via any communication channel).
The owner then submits the parameters along with the signature to the blockchain, paying for gas. The signature guarantees that the message was approved by the user.
Refund used gas at the end of the transaction. A modifier refundGasCost can be used for this (see below).
But (1) is really hard to apply to token transfers where you just don't know who uses the token and (2) does not really address the issue.
There is a lot happening recently, there is this blog post about How to save your Ethereum Dapp users from paying gas for transactions, and since you ask about tokens, there is an ERC that suggests to Pay transfers in tokens instead of gas, in one transaction which would be nice if you have tokens but no ETH.
I hope this helps.
Exactly this case is already defined in the ERC20 standard. Its this function:
function transferFrom(address from, address to, uint tokens) public returns (bool success);
But before party C could use it and send tokens from A to B, A would have to approve C to do this via the following function, which is also defined in the ERC20 standard:
function approve(address spender, uint tokens) public returns (bool success);
No, in a standard ERC20 token contract, the token holder must initiate at least one transaction (to call transfer() or approve()), and a transaction must always be paid for by its initiator.