If I only get an Ethereum address from the input, is there a way to find out whether it matches the ERC20 token standard?
To view your ETH or ERC-20 address, navigate and select the Deposit Ether Directly tab. Then click on View Account to see and copy your address. You can now paste the Ethereum address on airdrop portals requesting an ERC-20 address to receive free tokens.
One of the most significant smart contract standards on Ethereum is known as ERC-20, which has emerged as the technical standard used for all smart contracts on the Ethereum blockchain for fungible token implementations.
Each Ethereum address has a code field associated with it. If the address is not a smart contract, this field would be empty. If the extcodesize checks the code size of the address is zero, then the address is a regular one. If it finds the code size greater than zero, it is a smart contract.
ERC165 tackles this problem, but, unfortunately, most ERC20 implementations don't support it (as of Nov 2018, at least OpenZeppelin doesn't). This means that you could try calling the supportsInterface function, but it would revert anyway and you'd rather complicate things.
Nevertheless, here's how it's defined in ERC721:
bytes4 private constant _InterfaceId_ERC721 = 0x80ac58cd;
/*
* 0x80ac58cd ===
* bytes4(keccak256('balanceOf(address)')) ^
* bytes4(keccak256('ownerOf(uint256)')) ^
* bytes4(keccak256('approve(address,uint256)')) ^
* bytes4(keccak256('getApproved(uint256)')) ^
* bytes4(keccak256('setApprovalForAll(address,bool)')) ^
* bytes4(keccak256('isApprovedForAll(address,address)')) ^
* bytes4(keccak256('transferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
*/
Although it's not guaranteed for all implementations to define the interface id, there's a higher chance it will work in the case of ERC721, given the fact the community agreed on applying ERC165 right from the get-go. If the return value of the query below is true, then it means you have a compliant contract, otherwise just revert the transaction.
// you can call this in your contracts
IERC721(contractAddress).supportsInterface(0x80ac58cd)
Also, a useful resource for manually checking the bytes4
of a given method is 4byte.directory
If you are asking about off-chain, so use these functions:
getContract(url, smartContractAddress){
const Web3Eth = require('web3-eth');
const abi_ = this.getABI();
const web3Eth = new Web3Eth(Web3Eth.givenProvider || url);
return new web3Eth.Contract(abi_, smartContractAddress);
}
async getERCtype(contract){
const is721 = await contract.methods.supportsInterface('0x80ac58cd').call();
if(is721){
return "ERC721";
}
const is1155 = await contract.methods.supportsInterface('0xd9b67a26').call();
if(is1155){
return "ERC1155";
}
return undefined;
}
getABI(){
return [
{"constant":true,"inputs": [
{"internalType":"bytes4","name": "","type": "bytes4"}],
"name": "supportsInterface",
"outputs": [{"internalType":"bool","name": "","type": "bool"}],
"payable": false,"stateMutability":"view","type": "function"}
];
}
like this:
const contract = getContract(url, smartContractAddress);
const type = await getERCtype(contract);
console.log(type);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With