如何检测以太坊地址是否是ERC20令牌合同?

kai*_*hen 6 ethereum solidity erc20

如果我只从输入中获得以太坊地址,有没有办法找出它是否符合ERC20令牌标准?

Pau*_*erg 8

ERC165解决了这个问题,但不幸的是,大多数 ERC20 实现不支持它(截至 2018 年 11 月,至少 OpenZeppelin不支持)。这意味着您可以尝试调用supportsInterface函数,但它无论如何都会恢复,并且您宁愿让事情变得复杂。

尽管如此, 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)'))
 */
Run Code Online (Sandbox Code Playgroud)

尽管不能保证所有实现都定义接口 id,但考虑到社区从一开始就同意应用 ERC165,它在 ERC721 中工作的可能性更大。如果下面查询的返回值为 true,则意味着您拥有合规合约,否则只需恢复交易即可。

// you can call this in your contracts
IERC721(contractAddress).supportsInterface(0x80ac58cd)
Run Code Online (Sandbox Code Playgroud)

bytes4另外,手动检查给定方法的有用资源是4byte.directory


Sil*_*des 5

如果您询问有关链外的信息,请使用以下功能:

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"}         
    ];
}
Run Code Online (Sandbox Code Playgroud)

像这样:

const contract = getContract(url, smartContractAddress);
const type = await getERCtype(contract);
console.log(type);
Run Code Online (Sandbox Code Playgroud)