简体   繁体   English

如何检测以太坊地址是否为 ERC20 代币合约?

[英]How to detect if an Ethereum address is an ERC20 token contract?

If I only get an Ethereum address from the input, is there a way to find out whether it matches the ERC20 token standard?如果我只从输入中得到一个以太坊地址,有没有办法找出它是否符合ERC20 代币标准?

There are many possible ways to achieve this. 有许多可能的方法来实现这一目标。 One possible quick and dirty solution is to check if a ERC20 function exists on the contract address by calling the following: 一种可能的快速和肮脏的解决方案是通过调用以下内容来检查合同地址上是否存在ERC20功能:

eth.call({to:contractAddress, data:web3.sha3("balanceOf(address)")})

A non-ERC20 will return a 'null' 0x hex response whereas an ERC20 will give you a 32byte uint , in this case 0 but if you provide an address in the data then it will give you the actual token balance for that address. 非ERC20会返回一个“空” 0x六角响应,而一个ERC20会给你一个32字节uint ,在这种情况下0,但如果你的数据提供了一个地址,然后它会给你该地址的实际令牌平衡。

This is not a guaranteed way of determining a contract is ERC20 since other contracts may expose the same function, however it is a quick and easy check. 这不是保证合同是ERC20的保证方式,因为其他合同可能会暴露相同的功能,但这是一个快速简便的检查。 You could add additional calls on totalSupply() etc. for more confirmation. 您可以在totalSupply()等上添加其他调用以获得更多确认。

ERC165 tackles this problem, but, unfortunately, most ERC20 implementations don't support it (as of Nov 2018, at least OpenZeppelin doesn't ). ERC165解决了这个问题,但不幸的是,大多数ERC20实现都不支持它(截至2018年11月,至少OpenZeppelin 没有 )。 This means that you could try calling the supportsInterface function, but it would revert anyway and you'd rather complicate things. 这意味着你可以尝试调用supportsInterface函数,但无论如何它都会恢复,你宁可复杂化。

Nevertheless, here's how it's defined in ERC721 : 不过,这里是它在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. 虽然并不能保证所有实现都能定义接口ID,但是在ERC721的情况下,它有更大的可能性,因为社区同意从一开始就应用ERC165。 If the return value of the query below is true, then it means you have a compliant contract, otherwise just revert the transaction. 如果以下查询的返回值为true,则表示您具有合规合同,否则只需还原该事务。

// 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 此外,用于手动检查的有用资源bytes4给定方法的是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);

I am amazed by the answers that are provided.我对所提供的答案感到惊讶。 (I either do not know anything about Ethereum or I do not understand English at all) (我要么对以太坊一无所知,要么根本不懂英语)

the question states that given an Ethereum address, is this an Ethereum contract address or not?问题指出,给定以太坊地址,这是否是以太坊合约地址?

First thing, you have to decide if this address is a contract address or an externally owned account address.首先,你必须确定这个地址是合约地址还是外部拥有的账户地址。 How to find out if an Ethereum address is a contract 如何确定以太坊地址是否为合约

If it is a contract address, then you can only get the bytecode that is stored in the blockchain.如果是合约地址,那么你只能获取存储在区块链中的字节码。 Now you have to reverse engineer the bytecode to get the contract functions but this is almost impossible.现在你必须对字节码进行逆向工程才能获得合约功能,但这几乎是不可能的。 There are some decompilers but they are not perfectly creating the contract code from the bytecode.有一些反编译器,但它们并不能完美地从字节码创建合约代码。

ERC165 just checks if the current contract signature supports the given interfaceId or not. ERC165只是检查当前合约签名是否支持给定的 interfaceId。 Since you have only ethereum address, this will not help in this question.由于您只有以太坊地址,因此这对这个问题没有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何创建一个erc20代币生成器,其中创建合约的账户地址是唯一erc20合约地址的代币持有者? - How to create a erc20 token generator where the account address creating contract is the token holder of unique erc20 contract address? 以太坊ERC20代币合约通过重新混合部署的合约地址添加到钱包时返回0.00代币余额 - Ethereum ERC20 Token contract returns 0.00 token balance when it added to wallet by remix deployed contract address ERC20代币余额如何存储在以太坊区块链上 - How ERC20 Token Balances are stored on the Ethereum blockchain 如何使用 PHP geth 通过合约地址获取 ERC20 代币名称和符号 - How to get ERC20 token name & symbol by contract address with PHP geth 如何从以太坊地址获取ERC20,ERC721和ERC827令牌的列表 - How to get lists of ERC20, ERC721 and ERC827 tokens from Ethereum address 如何在其智能合约中签署 ERC20 代币转账 - How is an ERC20 token transfer signed in its smart contract 如何将 ERC20 代币发送到智能合约余额? - How to send ERC20 token to smart contract balance? ERC20 代币智能合约如何运作? - How does a ERC20 Token Smart Contract work? ERC20 代币转移到智能合约 - ERC20 token transfer to smart contract 如何使ERC20代币持有者的钱包地址保密? - How to keep wallet address of an ERC20 token holder private?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM