-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NFT NEP-171 require having minting/burning interface #254
Comments
I want to highlight that currently Wallet uses some hacks that only allows it to find potential FT / NFT contracts that the account might be involved with and then tries to fetch the balance from there. There are several problems with that:
Explorer is also blocked on it since we want to display a feed of events instead of just pure transactions (e.g. when FT is transferred, the receiver account might not be even touched b native NEAR receipts and thus Explorer won't display those incoming transfers in the first place) It is a complex topic, but we want to raise it sooner rather later to benefit across the ecosystem and make NEAR user and developer friendly platform! |
@jberrytech Hey, Jim, Node Interfaces team has not been part of FT and NFT standards, but to support our end-user needs we dived into the current status of the things and found that the things are quite in flux and we need to have some decision made here. At the current stage, Wallet and Explorer are blocked on Indexer for Explorer, and Indexer for Explorer is blocked on the standards being completed and followed by the dApp developers. |
I had a discussion today with @ilblackdragon and it seems that there is a set of minimum requirements for FT and NFT tokens to make them useful across the ecosystem (I will use FT as a simpler example):
Originally, I wanted to rely on called method names ( |
For NFT, spec is also missing here. UPD: we actually have, so everything is OK here |
Are you saying that minting and burning of the tokens do not emit the corresponding logs according to the standard? |
I agree, it is critical that FT and NFT standards define logs, given that we currently do not have proper Ethereum-like events. Ethereum events are part of the contract ABI, along side method signatures, and various integration tools heavily rely on their standardization to work with the contracts. E.g. see minting event https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.1.0/contracts/token/ERC20/ERC20.sol#L236 CC @jberrytech @DiscRiskandBisque @mikedotexe |
Just got off a call this morning with Mintbase, Paras, Matt Lockyer, and Austin. Agree we need logs as events. The time has come. I believe standards will likely need far more attention and prioritized org-wide. |
I want to cross-post by comment here: #256 (comment)
|
Thanks @frol for elaborating previously. If we talk about I propose a royalty standard which will help minting spec. This is not standardised in general because payouts of fractional royalties is natively infeasible for many blockchains. NFTs should have royalty standard because majority use case serves that purpose. This is brief draft of the spec - https://nep-docs-typescript-site.netlify.app/interfaces/nft.proposalbatch.royaltyargs |
@frol for events perhaps we could be more terse with just 2 events approvals and transfers. Where transferring from a null address is minting, and transferring to a null address is burning. Then indexers and consumers can just watch those events to understand what's happening with the contract. Across the pond in eth land this is what happens for 721/1155. Curious what people think about this? |
Curious here just watched the recap of the meeting. I have questions with regards to #245. I think @telezhnaya you mentioned that events being emitted from unknown methods is problematic? Is it that events can only be emitted from known methods ? Is that what's driving extending the standards to include mint and burn, despite the addition of events? With erc-1155 many methods and even I think across ethereum, many methods use all manner of name and method signatures to mint tokens. For instance, one anti-NFT bot measure that's gaining traction, takes a signed nonce as an argument, to verify, before the user is able to mint. I think there's a little more diversity in the minting. So my mild concern about would be something like the buy methods here from 2 popular NFT contracts that get cloned a bit. Examples:
In the above examples minting functions are varied and called in multiple context with different arguments that make sense for the contract. Would the current events proposal and minting indexing be able to handle something like this? If mint and burn are part of the standard then does that hamstring use cases like the above and what do we gain? |
Thanks for this. I'm having a hard time understanding what specifically is needed on the royalty standard. Maybe I need a bit of a user story or a practical example for me to understand. Forgive me, as I'm not working with NFTs every day anymore, not for 8 or so months. :) |
Catching up on all of this and it's a heavy amount to context-switch to. I think as we iterate on the NEP process, it's going to be most helpful for folks who have firsthand experience of NFT and indexing issues to really drive the suggestions. I think I'm almost caught up but will have to learn more. I might be most helpful reviewing other peoples' ideas, but will be the author and open a pull request if that's the best way forward. Here's my take: Fungible tokens and non-fungible tokens are supposed to have multiple extension standards. Even ERC-721 for NFTs has metadata as an optional extension standard, even though it's hard to imagine an NFT without it. In a similar vein, there will be fungible tokens that simply never mint new tokens, like when the token supply is set upon initialization of the contract and should never change. Burning is a little different for us simply because we have state storage and an individual can opt to "remove themself" as a key value pair. If that person decides to forcefully ragequit a fungible token contract and has a non-zero balance, we must determine what to do with their tokens. Perhaps it goes to the "token owner" and the total supply remains unchanged, or perhaps it disappears (burns) and total supply is reduced. This is why we have this section in the fungible token example which utilizes the fn on_account_closed(&mut self, account_id: AccountId, balance: Balance) {
log!("Closed @{} with {}", account_id, balance);
}
fn on_tokens_burned(&mut self, account_id: AccountId, amount: Balance) {
log!("Account @{} burned {}", account_id, amount);
}
}
near_contract_standards::impl_fungible_token_core!(Contract, token, on_tokens_burned);
near_contract_standards::impl_fungible_token_storage!(Contract, token, on_account_closed); That was a little bit of a tangent but the punchline is, "people don't have to have explicit minting or burning functions" and I believe this should be an optional extension standard, both for FT and NFT. Next, I believe indexers like Wallet and Explorer must be able to parse both:
I want to say that explicitly, and if someone reading this believes we should have only one, please speak up, but I don't think that's the case. Now, we have to decide if mint and burn should be parsed by:
I believe it should be either As Max pointed out, the OpenZeppelin implementation contains minting and burning, and here's what NFT mint looks like:
I see that Pluminite included more arguments: pub fn nft_mint(
&mut self,
token_id: Option<TokenId>,
metadata: TokenMetadata,
perpetual_royalties: Option<HashMap<AccountId, u32>>,
receiver_id: Option<ValidAccountId>,
token_type: Option<TokenType>,
) { I see Paras is doing something a bit different, that seems to deal with token series, perhaps more adjacent to a multi-token: pub fn nft_mint(
&mut self,
token_series_id: TokenSeriesId,
receiver_id: ValidAccountId
) -> TokenId { Looks like Mintbase is doing batch mint. Given the above scenarios, and if we all agree that one way to have observability of new tokens is via method name/signature, then perhaps what we need is three arguments, where the third is optional and free-form. Perhaps what OpenZeppelin is doing, by having only two arguments for the receiver and token ID, will not be as future-proof as we'd like and we'd prefer the option to provide extra detail about this mint. Mint function suggestion// This method is expected to mint one NFT. If custom logic exists to mint more than one,
// events must be used in order for indexers to pick this up.
// Arguments:
// * `receiver_id`: the valid NEAR account receiving the newly-minted token.
// * `token_id`: the token ID to mint.
// * `msg`: specifies information needed during the minting process.
// It is up to the contract to parse this extra data.
// If it contains data that is intended to be indexed, it must use an event.
function nft_mint(
receiver_id: string,
token_id: string,
msg: string|null,
) {}
Event log suggestionEVENT_JSON:{
"standard": "nep171",
"version": "1.0.0",
"event": "mint",
"data": [
{
"receiver_id": "frol.near",
"token_id": "NEAR:mainnet/nep171:gcp.mintbase1.near
:HMSu9SnnW9LiVvVDemLsGH_jhn2NZQNAuxUvqaWMOes"
},
{
"receiver_id": "mike.near",
"token_id": "19"
}
],
} The above suggestion has the
Lastly, I think I heard some concerns about people "misusing event logs" and possibly not doing it right. Just as a reminder, standards are written for the "good actors" and there's nothing we can do to stop anonymous, malicious behavior. All we have the power to do is provide suggestions that bring order to the collaboration between good actors. I think it's a great instinct to try to determine what might go wrong, but we can never force contract authors to implement according to standards or to play nice. The community and market will determine which contracts, markets, and dApps will survive, and those will be the ones that are orderly and act as expected. |
@zcstarr
@mikedotexe provided the answer much better than I can give. 😄 But I want to add few words from Indexer's perspective. Indexer still doesn't have any solution for FT/NFT, but I've made a draft for FT. We go through all function calls, filter from them By the way, I'm OK with logs + the fixed function name with any parameters as you wish. This is enough from our side to identify needed function call, this gives the freedom to developers as @zcstarr was asking for. The only concern here is that it can't be strictly defined in NEP, I never seen such conditions before. @mikedotexe what do you think? If we decide to choose the solution only with logs (I will be upset but anyway), could we mention in NEP that the method should have
New interesting scenario for Indexer to handle this correctly, thank you for mentioning that. |
I've created a PR for the minting standard. We implemented it in Cheddar. I think burning should be a separate trait. Not every coin will support burning. |
We made a PR for wallet which was merged and the following (mentioned above) #249 for the mint spec. |
@mikedotexe great write up! I think you mentioned a very good point about account storage management burning tokens, additionally within the ecosystem I think there are a lot of new use cases and usage patterns, where a contract's burn and mint might happen in the same method. One emerging pattern is combining NFTs as well as burning NFTs to mint NFTs, so it's worth considering context. Do we think this will be a permanent indexing drag, where log filtering will always be not performant, I think |
Whenever you mint an NFT, on a store, it is store's responsibility to implement payout - value is tied to store not NFT. How will store A know to pay me when store B keeps this information. Marketplace interoperability not going to happen like this. My thought. |
@frol I am proposing this as event logs for // nft_batch_mint
{EVENT_JSON:{
"standard": "nep171",
"version": "1.0.0",
"event": "nft_batch_mint",
"data": [
{
"account_id": "frol1.near",
"token_id": "0"
},
{
"account_id": "frol2.near",
"token_id": "very_long_token_id"
},
]
}}
// nft_batch_burn
{EVENT_JSON:{
"standard": "nep171",
"version": "1.0.0",
"event": "nft_batch_burn",
"data": ["1","2","3"]
}}
// nft_batch_transfer
{EVENT_JSON:{
"standard": "nep171",
"version": "1.0.0",
"event": "nft_batch_transfer",
"data": [
{
sender_id:"sender.near",
"to":"receiver1.near",
"token_id":"0"
},
{
sender_id:"sender.near",
"to":"receiver2.near",
"token_id":"very-long-token-id"
},
]
}} Due to the 16k string limitation, different stores will have different output. As long as this is documented, it is acceptable. This change is reflected #256 |
@evergreen-trading-systems thank you for the proposal! I have few comments:
|
@telezhnaya thanks for your comment.
These changes can be seen https://github.com/evergreen-trading-systems/NEPs/blob/feature/batch/specs/Standards/NonFungibleToken/Event.md. Updated pr too. I don't know if |
@evergreen-trading-systems Thanks for championing the work on writing the proposal! Here are few items I heard people had concerns:
Reviewing the latest version from here, I noticed that mint and burn methods are not symmetric: you can mint a given token for a corresponding account, but you can only burn tokens for a single owner. Another asymmetry is |
Thanks for looking at this @frol
|
Thanks everyone for the recent work here. Returning to this question from Olga, I want to check with @MaximusHaximus (Wallet team) as I seem to recall concerns about folks using these somewhat "special" prefixes ( Seeing that bloom filters are not anticipated to happen anytime soon, and Olga's concern about needing some indicator to "please check for log events in this transaction" I think I hesitantly agree with Olga here. I would love it if these special prefixes were supposed to only be used for methods that abide by a standard, but I can't think of better options at this time. Are there objections to this? |
I'm going to agree with Frol on this, and perhaps I didn't explain my initial reasoning in an earlier comment. At some point, NEAR will have binary logs like Ethereum but we're not quite there yet. Until then, we can use a prefix like I can imagine other prefixes like |
@telezhnaya What exactly is the problem for analyzing all the logs on the Indexer side? As far as I understand all the transaction and their results are getting processed and put into the database. Given we define proper format of the logs, this processor should parse them out and put them into respective places. I would expect we would just have a single logs table containing all logs from all contracts. This is how all the indexers work right now as far as I understand in Etheruem, hence I'm not fully understanding why we need to optimize for function names for events (see below cross post why function name don't work). Then separate view/indexing process can do specific things for FT and NFT based on specific log format in those standards. Cross posting from #249 (comment)
|
@ilblackdragon Olga assumed that at maxed out tps and maxed out logs we may hit the performance issue unable to process a chunk. I believe that is not the case, so we will proceed and parse all the logs. |
@ilblackdragon I wanted to minimize the possibility of parsing something completely irrelevant, but accidentally in the same format. I am OK with parsing all logs from all functions. Thank you for the explanation with the different scenarios! |
I am dedicated to seeing NFT core events - I've updated the proposal accordingly. Can we get eta when the wallet will listen for events if nothing else is outstanding? |
Please have a look at the PR that I just created.
@evergreen-trading-systems @zcstarr @robert-zaremba |
Based on #256 (comment) its obvious event format vs specific event data format e.g. We're already clear on what an event should look like in maybe formats potentially e.g. Binary, RLP, Borsh, etc. This pr addresses that https://github.com/near/NEPs/pull/268/files Specific events - |
Our users ask for supporting FT/NFT in the tools such as Explorer and Wallet. We want to show FT/NFT balance and the history of all FT/NFT movements.
To achieve that, we need to track all the FT/NFT balance-changing events. They include minting, transferring, and burning of the tokens.
For now, it's only possible to track transfers.
While digging into FT implementation, we've found
internal_transfer
method, it looks like what we need. But it's the details of one exact implementation, and it's not possible to catch these calls, it's deep inside the contract. We can only see public interface calls such asft_transfer
.It’s a critical moment for supporting FT/NFT in our and 3rd-party tools, our data would be incomplete in other cases.
We should include minting/burning in NEPs. Without that, we are blocked, we can't show valid FT/NFT balances.
Please share any thoughts, including other workarounds to solve the issue.
Previous issue #250
Issue with collecting balance-changing events in Indexer for Explorer near/near-indexer-for-explorer#153
@chadoh @mikedotexe @mattlockyer @MaximusHaximus @jberrytech @frol
The text was updated successfully, but these errors were encountered: