-
Notifications
You must be signed in to change notification settings - Fork 11.8k
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
ERC1155: Add a simple catch-all implementation of the metadata URI interface #2029
Conversation
* Initial ERC1155 implementation with some tests * Remove mocked isERC1155TokenReceiver * Revert reason edit nit * Remove parameters associated with isERC1155TokenReceiver call * Add tests for approvals and single transfers * Add tests for transferring to contracts * Add tests for batch transfers * Make expectEvent.inTransaction tests async * Renamed "owner" to "account" and "holder" * Document unspecified balanceOfBatch reversion on zero behavior * Ensure accounts can't set their own operator status * Specify descriptive messages for underflow errors * Bring SafeMath.add calls in line with OZ style * Explicitly prevent _burn on the zero account * Implement batch minting/burning * Refactored operator approval check into isApprovedForAll calls * Renamed ERC1155TokenReceiver to ERC1155Receiver * Added ERC1155Holder * Fix lint issues
Thanks @KaiRo-at! You should add a new file in the If you have any specific doubts please ask! |
One more thing. We recently migrated our tests to OpenZeppelin Test Environment. The Keep in mind Mocha's |
Hi all! |
Hi folks! |
I just added a test to my repo, but I have issues running tests, I get an |
Hello @KaiRo-at! From your description, it sounds like your import statement is wrong: you should import And yes, feel free to ignore linting errors for now :) |
I guess so - I copied from the other ERC1155 tests on that feature branch and it looks like it's wrong there as well... ;-) |
Looks like you're right! The feature branch was created before we migrated our testing setup to use Test Environment. I updated the branch to bring the ERC1155 tests in line with the old ones, and then updated your own branch to use those. You should now be able to get your tests working! Just remember to run |
Thanks for that, needed a bit of merging as I was working in parallel, but I should have tests up and running now. :) |
Have you tried using const contract = await MyContract.new();
await expectEvent.inConstruction(contract, 'Foo', { value: 'bar' }); |
Thanks, that's great! From what I see, everything should be complete for adding the URI feature now. :) |
Hi all! |
Sorry @KaiRo-at for taking so long to review this! I'll take a look tomorrow. |
Hi all! |
Hi folks! |
Erm, @nventuro - I don't think this should have been closed... |
It shouldn't have, no - I'm reopening it. I'm very sorry @KaiRo-at, I've been working on the v3.0 pending changes and haven't managed to get around to reviewing 1155-related PRs yet - the same thing applies to #2107. I'll take a look at this as soon as I can. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry it took so long to get here @KaiRo-at, but the time for ERC1155 has finally come!
Given the work we've done on including optional extensions into the base implementation in ERC20 and ERC721, and the fact that URIs are an almost mandatory feature of NFTs, I was wondering if we could figure out a way to include this in the default ERC1155 contract, perhaps following a scheme similar to the baseURI from ERC721. What if we had a 'fallback' URI, allowing users to replace it with a token-id specific one if they desire? Concatenating the token id doesn't seem necessary, given the string substitution requirements of the spec.
*/ | ||
function _setURI(string memory newuri) internal virtual { | ||
_uri = newuri; | ||
emit URI(_uri, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems sensible, but I couldn't find anything in the specification about the event's id
argument in cases such as this. Given that an id
value of 0 is valid, perhaps we shouldn't emit the event at all? The spec seems to allow this:
Changes to the URI MUST emit the URI event if the change can be expressed with an event (i.e. it isn’t dynamic/programmatic).
An implementation MAY emit the URI event during a mint operation but it is NOT mandatory. An observer MAY fetch the metadata uri at mint time from the uri function if it was not emitted.
The uri function SHOULD be used to retrieve values if no event was emitted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, you mean "it isn't dynamic" says that the {id}
pattern doesn't need it? I interpreted it as it can only be omitted if e.g. the URI is built by a function that depends on, say, other fields and the actually returned URI changes dynamically - but in our case, it can be expressed by an event, and the actually returned URI doesn't change dynamically, it changes only with that call. I have wondered about the ID in that event as well though, unfortunately, the spec doesn't define this case. Maybe we should ask there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I agree with your interpretation and believe this case might be missing from the spec. Emitting an event feels wrong though because there is no invalid values for the id
field we can use to signal what is going on. Asking the spec authors sounds like the way to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At any rate, given the spec allows for no events to be emitted (like in the case of dynamic URIs), I think it makes sense to not emit anything here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At any rate, given the spec allows for no events to be emitted (like in the case of dynamic URIs), I think it makes sense to not emit anything here.
We definitely interpret the spec differently there, as I read it as non-optional, with the only exception being where it is not static and not possible to emit the event - and it is static in our case and very much possible to emit it. But if you as the reviewer(s) prefer that, I'll remove it even if I disagree. ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've also discussed this bit with @frangio and agree that we should not emit any events. The spec clearly allows for situations where no events have been emitted, as seen in these statements:
The uri function SHOULD be used to retrieve values if no event was emitted.
The uri function MUST return the same value as the latest event for an _id if it was emitted.
Starting on Solidity v0.6.2, interfaces can now inherit. \o/ Co-authored-by: Nicolás Venturo <nicolas.venturo@gmail.com>
We could do that. That said, given that the ERC1155 spec contains this |
Sorry, I should've been clearer. I wasn't suggesting using
|
Sorry I have been silent on this and the other issue for a bit, but we just shipped (and sold out) our Crypto stamp 2 presale today using the code from here and the other ERC1155 contributions: https://etherscan.io/address/presale.cs2.cryptostamp.eth#code |
No worries, and congratulations on your release! 🎉 |
I definitely can do that. I concentrated on the single catch-all solution for now due to #2014 (comment) and I was planning to look into extending that for per-token URIs once ERC1155 was on master if my time allowed for it. But I can look into the right here as well. |
Good point, thanks for reminding me of that. I've discussed this with @frangio and came to the conclusion that, given there's a clear pattern on how to use URIs with string substituion, we can do without |
@KaiRo-at we're aiming to release v3.1 soon and to include initial support for ERC1155 there, so if you don't mind I'll go ahead and make the final changes required for this PR myself :) |
I added the optional extension to I additionally changed some |
Sure, I don't feel territorial about this, happy I could push it along some way. Sorry I'm pretty short on time recently (due to a lot of ongoing work for Crypto stamp 2), I'm happy this work here gets picked up and driven into a release! |
Reviewed offline by @frangio. |
As mentioned in #2014 (comment) this is a simple implementation of the metadata URI part of ERC1155.
I'm still a bit confused on how to do tests for OpenZeppelin (this is my first PR to the project), so I have not added tests in this PR for now. Help would be appreciated.