I want to know 3 things:
- Is an address a smart contract?
- Is this smart contract an ERC20 or ERC721 token?
- Is the Solidity code public?
It is unclear what layer you want to find out this information on (on-chain or off-chain). In general:
Is an address a smart contract?
This can be checked by seeing if there is associated code at the address.
Is this smart contract ERC20 or ERC721 token?
Off-chain, you can check this by observing the contract on Etherscan. There are also interfaces you can work with that will tell you the same thing.
Is the code public?
The bytecode is public. Technically, you can deconstruct this into Solidity. In some cases, the author publishes the source code. Here is an example of a verified contract on Etherscan where you can see the source code.
For 1 you may use
web3.eth.getCode(address) function of Web3 API. For contract addresses it returns contract byte code, while for non-contract addresses it returns something like
For 3 it depends on what "public" means for you. If you mean whether smart contract has verified source code published at Etherscan.io, then you may use either API call to obtain source code by contract address, or download full list of all contract addresses that has source code verified: https://etherscan.io/apis#contracts .
The 2 is most tricky, because there is no reliable way to know whether smart contract implements particular interface or not, other than analyzing its source code. Though there could be some hints. You may check whether smart contract ever logged
Transfer(address indexed, address indexed, uint256) (for ERC-20) or
Transfer(address indexed, address indexed, uint256 indexed) (for ERC-721) event, but this way you will not recognize token contracts whose tokens were never transferred yet.