Closed Vectorized closed 2 years ago
It seems like I have seen this debate between small cap/large cap a few times now. Thoughts on creating a "small cap" extension that could include multiple functions that might only be possible for these small cap collections?
I have a question related to tokensOfOwner
usage, Is checking for owners tokens on-chain really necessary?
Doesn't Off-chain APIs like Moralis do the job?
I have a question related to
tokensOfOwner
usage, Is checking for owners tokens on-chain really necessary? Doesn't Off-chain APIs like Moralis do the job?
Nothing against Moralis, but if it could be done without adding a 3rd party why would you make it a requirement to get this information? Also tokensOfOwner
may have use cases within the contract. Say you have some sort of functionality like nft_id % 4 == 0
and you need to find how many of these tokens the user owns. You will need a list of their current holdings within the contract. You can't do that if you rely on Moralis to what I assume keep track of the balances based on transfer events.
@Austinhs you want to avoid O(totalSupply) methods which introduces DOS risks.
IMO it's acceptable to add this to a contract situationnally if:
Otherwise it's quite straightforward to do this off-chain through contract logs, or (assuming a wallet has less than 10k transfer logs) even etherscan api https://api.etherscan.io/api?module=account&action=tokennfttx&contractaddress=${contract}&address=${address}&apikey=${apikey}
@Austinhs you want to avoid O(totalSupply) methods which introduces DOS risks.
IMO it's acceptable to add this to a contract situationnally if:
- your totalSupply is low enough to mitigate the DOS risk
- you have a functional need to do this on-chain
Otherwise it's quite straightforward to do this off-chain through contract logs, or (assuming a wallet has less than 10k transfer logs) even etherscan api
https://api.etherscan.io/api?module=account&action=tokennfttx&contractaddress=${contract}&address=${address}&apikey=${apikey}
Yeah I tend to agree with this like @Vectorized originally said this works well with majority of the low cap supplies <= 10,000 which 90% are. But a collection for example like crypto kiddies that have breeding and can easily hit 100k+ are the problem here. I think I will move this into a ERC721ALowCap
extension that will allow helper functions like this to exist.
Also there is the option to just not add this -- but personally I've been doing some community service in twitter spaces to help newer dev's and ERC721A is a common topic. It would be hard for a newer dev to understand the architecture of ERC721A. Especially how to read the data, so I've actually been pointing them to this function to just explain how reading from ERC721A is a bit more complicated, I think adding a helper extension like ERC721ALowCap
would be very beneficial in that regard
Updated #114 to add this as a extension
What we did is just remove ERC721Enumerable from our version of the ERC721A contract. In my opinion most projects just don't require this functionality and it's just not necessary to include it. The only function we keep from ERC721Enumerable is totalSupply()
which is an obvious necessity.
I'm having a hard time understanding why a project would need the extra ERC721Enumerable functions. Is it just so that they can easily enumerate an address' owned tokens so they can display them on their project website or some other frontend environment?
Would love some clarification, appreciate your help!
@kyokosdream I'm having a hard time understanding why a project would need the extra ERC721Enumerable functions. Is it just so that they can easily enumerate an address' owned tokens so they can display them on their project website or some other frontend environment?
Yes, some of the market places might require NFT should use ERC721Enumerable
. It is more friendly to list all tokens in frontend. If someone ask for this feature in future, we might implement enumerable
in extensions for developers to use.
Enumerable is useful when implementing staking UI and getting all the tokens of a specific wallet. It is always good to have the contract as a source of truth and not 3rd party API.
I agree with what is said above. On a ERC721 test project, I loop on balanceOf along with tokenOfOwnerByIndex to display on the frontend the nft minted by the connected address without using a third party service. In terms of user experience it seems to me to be a real plus. In terms of performance however I don't know if it's a good practice, I didn't know anything about smart contract until 2 months ago, and I'm working on marketing (no one is perfect...).
I'm interested if you have alternative solutions for that usecase.
Hi, i have 10.000 items in my collection can i use this function? Is there any possiblity that this function crash my contract or my dapp?
@justChargin 10k is safe.
We added this, could we close this issue now? @Vectorized
How can I call this function inside my contract? Why is it external
and not public
?
How can I call this function inside my contract? Why is it
external
and notpublic
?
Our general advice is that you shouldn't be doing that.
But if we will be more specific, please explain exactly what you're doing, and the sizes of all things involved.
@sayhicoelho It is marked external
on purpose, because it is intended only for off-chain queries.
Calling it on-chain is highly not recommended, as it can cost millions of gas for typically sized collections.
If you need to call it in your function (hopefully intended for off-chain queries), you can prefix it with a this.
.
tokensOfOwner
function is definitely quite useful for small capped collections(probably > 90% of the collections you see these days).
However, we have to consider the implications of including a O(totalSupply) function in the main library. Even if we know if it supports collections of 10,000 unique items, it is still probable that someone will use this function for a collection of say 100,000 unique items, and result in off-chain queries from Infura (Metamask) / Alchemy failing.
Even if we include a cautionary comment, someone might just not read it and use the function without understanding the caveats.
One possible way to provide users convenience, but still keep the main library general is to include this in an examples folder, instead of an extension.
Let me know what you think.
@fulldecent @cygaar
Related:
107