I've made two functions to interact with a local ERC20 token. Here they are:
pragma solidity ^0.5.0;
contract GardenTestContract {
function getBalanceOf(address _address) public view returns (bool, uint, uint, address) {
address sender = msg.sender;
(bool _success, bytes memory data) = _address.staticcall(abi.encode(bytes4(keccak256('balanceOf(address)')), (sender)));
(uint amount) = abi.decode(data, (uint));
return (_success, data.length, amount, sender);
}
function getTotalSupply(address _address) public view returns (uint) {
(bool _success2, bytes memory data) = _address.staticcall(abi.encode(bytes4(keccak256("totalSupply()"))));
(uint amount) = abi.decode(data, (uint));
return amount;
}
}
The address I'm passing to these functions is the address of the ERC20 token which is implemented like this:
pragma solidity ^0.5.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20Detailed.sol";
/**
* @title GardenTestToken
* @dev Simple ERC20 Token example yielding 10000 tokens pre-assigned to its creator.
*/
contract GardenTestToken is ERC20, ERC20Detailed {
// modify token name
string public constant NAME = "GardenTestToken";
// modify token symbol
string public constant SYMBOL = "GTT";
// modify token decimals
uint8 public constant DECIMALS = 18;
// modify initial token supply
uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(DECIMALS)); // 10000 tokens
/**
* @dev Constructor that gives msg.sender all of existing tokens.
*/
constructor () public ERC20Detailed(NAME, SYMBOL, DECIMALS) {
_mint(msg.sender, INITIAL_SUPPLY);
}
}
I'm working in remix, which is why the github import works as far as i know.
When i call getTotalSupply i get back the correct number of total supply (the INITIAL_SUPPLY value from the token contract). When i call getBalanceOf, things get confusing. I dont get the balance of the address that I'm calling from, but i just get 0. The decoded output from the remix console looks like this:
{
"0": "bool: true",
"1": "uint256: 32",
"2": "uint256: 0",
"3": "address: 0xf348328786984162e70f08d54a272427D810124b"
}
If i copy the address in this output into the remix GUI belonging the my deployed ERC20 contract, I get back the correct balance, and i do not know why or how this could be.
My remix is running against a local ganache chain through metamask and I'm compiling with 5.13. It also doesn't with the JavaScript VM.
I'm at a loss, any suggestions are welcome.
uint256(10) ** DECIMALS
instead of10 ** uint256(DECIMALS)
. Also, instead of multiplying by 10000, you could use(DECIMALS + 4)
. Lastly, you should use small letters for those 3 constants (name
,symbol
anddecimals
), otherwise you contract is not conforming to the ERC20 standards, and applications will not display your contract details (including details of transactions executed on your contract) correctly.abi.encode(bytes4(keccak256("balanceOf(address)"))
toabi.encodeWithSelector(bytes4(uint256(keccak256("balanceOf(address)") >> (256 - 4 * 8)))
, though I'm not entirely sure about this.yaya
means in your code, but I believe that you should be usingsender
there._address
tobalancOf
in your static call.