Metabolism Technical Summit - Beyond the Edition custom IERC721Drop extensions for fun & profit
ETHGlobal·Sun, Oct 9, 2022, 12:00 AM
Join Jem Gold of Zora for a talk titled, "Beyond the Edition custom IERC721Drop extensions for fun & profit", part of our Metabolism technical summit. Zora’s Metabolism hackathon is a virtual space for creative experimentation, bringing together some of the world’s best creators from a broad variety of categories and inviting them to design new digital spaces, on-chain tools, artistic experiments and more. Web3 is both one of the biggest paradigm shifts since the advent of the internet age and an ever-evolving inquiry into the societal possibilities of creative technology: no matter if you are a developer, an engineer, an architect, a musician, a theorist or seasoned NFT artist - we invite you to build hyperstructures with us with focus on NFTs, on-chain music ecosystems, a new generation of DAOs and Zora’s vast ecosystem of tools and smart contracts. Let’s build. Let’s create. Let’s imagine - together. From August 4 — 10th, 2022 we invite you to build the future creative on-chain ecosystem with the ZORA Protocol and ETHGlobal ---------------------------------------------------- Follow us: https://twitter.com/ETHGlobal Check us out: https://ethglobal.com Email us at: hello@ethglobal.com
Transcript
[Applause] [Music] so up next we've got another awesome talk uh this one by jumping gold i'm also on the zoro team um titled uh beyond the edition custom e i erc 721 drop uh extensions for fun and profit um so yeah i really look forward to this one jeff thank you so much for the time as well um and yeah feel free to uh mute um i'll get out of the way so you can share your screen share your video yeah you're already on it so awesome thanks so much for being here jim sweet thank you so much jacob and thank you ian and i hope that these two talks will pair with each other quite nicely um we didn't plan this so we'll see how it goes let me just share my screen awesome perfect lipstick thank you so much yep sweet okay cool um beyond the audition custom yeah 721 drops extensions for fun and profit this might be a tongue twister for talk okay so we recently launched zora creator and zoro creator is the simplest way to create auditioned erc 721 tokens on artist's own contracts it has a super simple interface and it's the most user-friendly way we think to create editions for images for videos for audio files things like that at its core creator is an interface for managing an underlying contract erc 721 drop it's a really good contract it strikes the balance between being fully featured and customizable and it's also extremely gas efficient i'm when i say gas efficient obviously price fluctuates based on gas prices youth prices and things like that but earlier this week it was you know in the ballpark of me i'm spending maybe fifty dollars to deploy my own contract and mints for collectors on that contract uh somewhere in somewhere in the ballpark of three dollars and this is on ethereum l1 there's no um you know there's no price savings from being on l2 nothing like that this is um this is full fat ethereum l1 as an artist i'm old enough to remember february 2020 where minting even single tokens on other platforms shared contracts cost hundreds and hundreds of dollars and so needless to say this is a really great contract but this isn't a talk hyping up how efficient our contract is out of the box ian has already showed you some amazing things you can do with this contract building your own websites and these contracts and i want to take us in a different direction what if out of the box erc 721 drop doesn't actually do everything that you need it to do what if you want to go beyond the functionality available ese 721 drop for example has a robust system for managing public sales and with options for sales that are timed or open-ended the sales that are free or paid available in fixed quantities or maybe unlimited runs we have lots of options baked into it but we also have no assumption that this is the only way that you might wish to distribute your nfts as an artist as a creator as a community perhaps you might want to get access to a pre-sale based on holding a threshold of your dao's erc20 perhaps you want to give a discounted mint to collectors of a previous erc 721 token if you want to do batch pricing or bundles things like that you might want to experiment with pricing on a bonding curve you might want to prevent people from minting tokens on on the sabbath these are all good use cases the same is true for the content of your tokens editions as you've seen them on creator are pretty simple they store a reference to one piece of media on ipfs that's you know whatever it is that goes on oh cool i can draw on the screen um you know whatever it is that goes in here um they store a reference to a piece of media and that is one piece of media the same for every token in an edition and this is great we use this and we use this ourselves for our drops and many many successful drops have come out using this exact methodology this is great but obviously that's not everything that you might want to do um with an nfc right maybe you're a musician and you want to store meaningful metadata on chain with each token maybe you've designed a tarot card deck and from an array of images from a whole deck maybe you just want to pull one card that was upside down um for each mint on the platform right um sorry maybe you want to pull one randomized image for each token that is mentioned maybe you're a generative artist and you want to do a project with a live code based renderer and a randomized seed per token along the lines of platforms like art blocks or fx hash or you know our favorite drops like solvencies and silk roads you know the type of job thoughtful handling of metadata is at the heart of every nft project and having full created control of it is absolutely pivotal for creators doing the paradigm pushing work that we are obsessed with at zora and as individuals so if you're running into any of these scenarios you might be tempted to say oh my god zora's contract sucks because i didn't consider my niche and didn't mean specific use case you might write a new contract from scratch maybe using base templates from open zaplin or soulmate you might fork our contracts tweaking the code so they work as you like and deploy your own version this is a hackathon these are all completely valid um these are all completely valid approaches right our contracts are on github and open source you can find them and go wild but we think there's a better way to go about it and a way to keep the majority of erc 721 drop as it is and to be able to rely on knowing that you're using the exact same base contract as we do it's optimized it's efficient and it's loaded with features that we think are really useful for creators who are doing industry leading work it turns out that our additions contracts as you've seen them on creator on kind of just the tip of the iceberg really the features that you see on creator the you know the ways you can instantiate an addition um on this screen is just one option for configurating an extremely customizable architecture of contracts modular contracts rather than forking erc 721 and dripping over yourself trying to keep um your own domain specific customizations separate from the majority of the zorro contract logic instead we have a way that you can extend them with discrete reusable chunks of logic these can even be designed in reusable ways so that when you deploy into mainnet your internet friends can use them for their projects as well we've seen a handful of drops using these techniques already but it's definitely not immediately intuitive i'm just gonna say it well the contracts are well designed easy to read and honestly they have really sick ascii um ascii diagrams in the comments that ian made should check them out if you haven't seen them there's still a lot of moving pieces and i know from my personal experience that it can be kind of overwhelming trying to figure out which page which places to poke around in first don't worry we've got you um for the rest of this talk we're going to show you how you might get started with two of my favorite pathways for customizing our drops contracts making uh custom metadata renderers and making custom minting modules before i get into that i want to stress that this is kind of advanced stuff right you might not need anything more than a standard editions contract deployed straight from zora creator if that's the case for you that's great like this is just an option available to people who want to push things further um than they can get with the out of the box contracts it's not an insinuation that you have to do things this way or this is what zora wants you to do these are um these are just options available to you with that said i think these techniques are really exciting and if you do something based on this i'm going to be stoked to see it so you know um this is also going to be a pretty solidity heavy talk um you don't need to be a solidity galaxy brain for this talk but you also might you should probably have done you know um an intro to solidity course you should probably have understood like at least like the basics of how an erc 721 drop um works at its core and if um if you listen to some of the examples that i shared a few minutes ago and you're like yes i want to do that um but maybe you don't have the solidity skills to implement it that's completely cool and i think funds are really good opportunities for you to pair up with people who do have that experience maybe you know get together and learn a little bit from each other so i just wanted to share that because this this might be a little bit um this is kind of zora 201 or 301 maybe but okay um also as max shared earlier we have a suite of composable tools that you can use at whatever level of abstraction that you are comfortable with so if you if you don't want to dive in so playing with zora toys um at the contract level well you know you can tap into whatever feels best for you and your level of programming experience and that might be using our typescript client that might be using the protocols uh graphql api that might be using our react hex that might just be using create.zora.com kind of as it is and so i just wanted to share that okay so let's start with custom metadata renderers as ian kind of touched upon earlier um the best place to start for this really is looking at how these contracts are created now the heart of this system um is a factory contract called zora nft creator v1 as i get into these on code leaning slides i just want to say my slides aren't online just yet um i'm going to format them a little bit more after this talk and i'll publish them probably sometime this afternoon so you'll be able to find those on the zora engineering twitter account i'll post those there so i just wanted to say that before i get into filling the screen with code okay so we have zora nfc creator v1 and if you look through that you might see a function called create edition which i believe ian was talking about it contains some pretty standard stuff for instantiating an erc721 a name a symbol details about the edition size and about the sales configuration and then down here at the bottom i don't know how to change the color of my marker but that's okay um down here at the bottom you know we have the details that you might expect from if you've used if you've created an edition on our website basically an animation uri an image uri and a description there's a sibling function um in this contract called create drop and similarly you know you have all your kind of standard erc 721 bits and pieces here instead what it does is it asks you for a metadata uri base and a contract uri this is really useful if you have your metadata that lives on a server somewhere um or you have um metadata that lives in ipfs you know based on uri base so you can configure it these ways you can interact with both of these contracts and however you like and you know whether that's in etherscan whether that's in foundry whether that's ethers personally i've been deep diving into foundry recently and i go to the huddle and i love it now so shout out foundry team um it's my favorite way to play with contracts from my text editor but you know if create drop or create addition don't suit the needs of your project well i promise you would go deeper so let's go a little bit deeper under the hood um each of these contracts call setup drops contracts and not yet again it's a public publicly callable function in i'm sorry nft creator and instead of passing in an image uri animation uri etc when you pass in i wish this highlighter was a different color and it's an iron metadata renderer okay um and a metadata initializer so let's figure out what eye metadata renderer is because i'm because it's kind of at the heart of all of this i metadata renderer is a really simple interface that we created and has three methods it returns the token uri for a given token it returns the contract uri the general contract and information for a different contract and it has a little function that we'll get into a little bit later that allows you to pass in some data from it from the factory or from wherever you initialize it so looking at addition metadata renderer this is kind of the um this is the this is the standard thing that we're all kind of familiar with at this point maybe um the addition metadata renderer is just one possible metadata renderer that can be used by any erc 721 drop it just so happens that on the zoro create website we have currently only implemented edition metadata renderer there are more coming soon you can create your own which is i guess what i'm talking about right now um how edition metadata renderer works it's pretty simple um like all we're doing is we have a struct token edition info and we pass it a description an image uri and an animation uri and then this renderer is shared between different contracts so multiple drops can use the same renderer without having to deploy it over and over again and this is really nice but you know it's nice and gas efficient um one second okay um we store this in a mapping um from the address the address per the address of the elc 721 drop to the token info and then in token uri you know if you've done any erc 721 project before if you've used open zapplan you know if you've done um uh you know solidity for zombies like anything like that you've probably kind of seen something like this before you've seen your token uri function that takes it it gets past the token uri and returns i need my pointer back and returns a string the string is the the json of the metadata right so the simplified version of this contract is that it gets the address of the drop from message sender oh the thing that i should explain is that these drops basically the drop contract will farm out it's called silken uri to the underlying metadata renderer so all it's saying is instead of having this token uri logic in my drop i'm just gonna store it somewhere else in a different uh in a different metadata renderer i'm delegate to that so we get the address of the drop from message sender we find our token info struct um from that address here and then you know like i said this is just an edition that has the same um it has like the same information per token id so like that's all we do and then we return it however you like to concatenate json so um you'll see sorry edition metadata renderer if you take a look at the code it's all on github and azura and additional today to render it it implements a couple of other functions it has some helpers that let for example like the contract administrator to update um some of the information and it has it has some bits and pieces that has an event that admits and such like that under the hood it's it's pretty much it's pretty much this it's pretty relatively easy to follow so you might want to start by taking a look into that and with that said it also means that if we you know if we want to create our own metadata renderer we really just have to follow this pattern on of implementing the i metadata renderer interface this thing going back we would pass it in when we're calling that setup drops contract we would have a deployed imeta data renderer and we would pass it in here so i just want to take a look at some patterns that might be useful i guess there's no syntax highlighting here and take a look at some patterns that might be useful and if you're creating your own metadata renderer so one thing is that um you might wish to make a metadata renderer that can work with multiple drops so instead of having one metadata renderer for one drop one metadata render for another drop deployed that gets pretty gas heavy um you know you might want to say there is a common set of reusable logic that different contracts can use on different drops contracts so what you might want to do is store except this is exactly what an edition metadata renderer does is we store a mapping from an address of a drop to some data type that could be you know a primitive it could be a string or a boolean or whatever it could also be a struct like we do in token edition in the flow you might also want to store um some data that is mapped both to the drop contract and also to a token ids in that case i would probably do something like a mapping of a mapping or whatever data structure feels good to you in that case to store data on a per token basis it also might be the case that you have an extremely extremely niche metadata renderer and you actually um you don't want to you know you don't want anyone else to be able to reuse it without redeploying it in which case go wild you do you i'm just saying these are some patterns that might be useful if you're implementing a metadata render of this weekend and you're looking at our code and you're like what is basically what is this first address parameter okay so with that said let's say you're making a music nft metadata renderer i hope someone does um and let's say you know you have some data that is useful to be stored on a per drop basis but you also want to have data that can be initialized one time just when the contract is deployed this is something that we do we have a library that you're free to use you're free to not use called shared nft logic which handles things like um you know have our json helpers and things like that you're free to use it you're also free to use a constructor you can pass that into the constructor and you're free to use a constructor wherever you like and this is at the global metadata renderer level and kind of a sibling patterns this is like cool okay well let's say um let's say you have your one deployed renderer and you want some custom data to be set for each drop that calls it again we do this in i'm in the addition metadata renderer and a couple of others so in that case the way that we handle this um to keep the function signature of i met a data renderer kind of consistent is to say instead of parameterizing it and based on different variables what we actually do is the abi encode those variables whatever shape they are whatever type they are and i've tried it with like strings and booleans and numbers and such things like things like that i presume it works with other things that can be api encoded and we call initialize the data and this is the other parameter that we passed to setup drops contract so we'd pass in our initialization data top tip if you don't need to do this pattern at all that's great you can just pass in an empty string when you call this function super chill you don't need to do this this is just an option but this is really great but this is exactly how we'd implement um you know in this case we want to set a custom image uri description animation uri on a per drop basis so we were to pass this in despite data and the api decode it you kind of it's kind of like destructuring in javascript if you haven't done this pass in in solidity before set whatever data type it is and then we're free to use it however we want another sibling pattern that might be useful is um well this is kind of got one it's using metadata render admin check so in the case that you um you know have a contract that is owned by a particular account um and you wish to um you wish to have some protected functions in there so in this case we're just storing mapping from an address to a string called token data see we only want our admin to be able to update this we have some we have some little helpers that if you just poke around in the zora drops contracts repo um you see that so this one's called metadata render admin check and you just import that and then you have a modifier that you can add to your function here i think that's like this section yeah cool okay um onto custom minters so this is actually really simple and kind of it's the other one was like kind of complex and also kind of relatively hard to do anything dangerous custom mentors i'm just gonna say be careful doing this it's in terms of like the code to implement it it's a relatively simple thing and you also have the potential to rug your whole project so with uh with great power comes great responsibility i guess okay so with that said all we're going to do to create a custom minter is from our drop so this is our drop that we've already deployed and again this can be this can be a drop that you've deployed um you can this can be a drop that you've deployed from ui on create.com really kind of however you want to do your draw and we have a drop and and we just want to grant that a role of mentor and granted a role of mentor to the mentor contract now these roles i was just using the open zaplin permissions model and these roles can be granted to other um externally owned accounts so you can you know give this to your friends on the team then they can rock the project as well um you know the humans and you can also say um you can also grant this to a smart contract so that's what we're doing when we make a custom mentor so all that you have to do if you've granted a mentor contract this role whether you've done that in either scan or whether you've done that and i do it in foundry just because i don't like typing the same thing over and over again and later this is in your and in your mentor contract you can just call admin and it it's like a back door to mint into the contract that bypasses all the traditional sales logic and again the nice thing about this is you can reuse them between all different drops so many different drops can just add these different minting modules without having to change their underlying erc 721 drop implementation you just grant one of these a specific role and then you're good to go i'm going to leave the implementation of these up to you because it's extremely domain specific again i guess and you know again i'm just going to say it you probably want to be testing these functions we've been using foundry writing a load of tests and buzz testing for things like i'm checking prices and stuff that's beyond the scope of this talk happy to help you later um but this is this is basically it now this contract doesn't implement any particular interface there's no particular signature that it needs to inherit or anything like that all we're saying is that we have a function it doesn't have to be called purchase either by the way this is just what i call that okay so we have a function called purchase that implements our custom logic now again this is like this is the skeleton you want to fill in the blanks here yourself so actually let's just look at the signature of what i've done i'm the signature takes a target and again this is an address of a drops contract you could also pass in the target in the constructor but again it's and you know to store it on the contract but it's kind of nice again to have these modular drops that will work with anything where your contract is an approved mentor so you can't call up on any contract this contract has to be approved but there you go um and all we're saying here is exactly like it was in the last slide and try admin minting to the message sender it doesn't have to be a message center it can be whatever you want it to be quantity is that's part of the signature of admin here this line up here or this the missing lines this is the fill in the blanks this is you want to be checking the price that you're letting people meant for you want to be checking any logic if this if you're token gating something this is where your token gate i know last weekend for zorotopia in oakland uh we implemented signature minting so that's where we do our signature checks again all of this is kind of out of the scope of what i have time for in one minute or maybe 30 seconds um but we're happy to help you if you have specific details but this is kind of the fill in the blanks it's also the kind of heavy dragons the other thing that's kind of useful i think um is this little snippet that we have here which again i'm going to publish these slides later um all we're doing here is saying um if the value that you're purchasing for is greater than zero basically if we're sending money into our mentor contract we should just forward that to our drops contract otherwise you're just going to end up with like money spread between um different contracts and that's kind of messy so yeah and really like implementing mentors is pretty simple um and also kind of dangerous i guess be really careful write your tests make sure you're only granting that role to contracts you trust etc etc and but that that is kind of the modular zoro way of creating these reusable chunks of logic that you can use across all of your projects you can configure in different ways and you can share with your friends and then again to recap if you want a custom metadata scheme that doesn't really work with our drops metadata renderer or edition metadata renderer we're just implementing i met a data renderer i think that is even more than i have time for right now thank you so much thank you jim this is awesome yeah simple and dangerous those are two words that one together can lead to amazing things and also very explosive things that's awesome and i got it gotta live on the edge gotta live on the edge well thank you so much for the for the talk and for the intro there again like i think another just back to back awesome talks from the zora team so far so lots of amazing resources for people as they build um i love that this one went even deeper um than the the last talk so yeah i think we did a 101 at 201 and now a 301 so um thank you so much for being here thank you looking forward to seeing what everyone builds and sorry the last postscript is that if you run into issues with this please reach out to us zoro engineering on twitter we're not just shitposts and memes and please ask us for help doing that stuff so looking forward to seeing what everyone builds thank you thanks so much
Automatic transcript — names and jargon may be misspelled.