Metabolism Technical Summit - ZORA’s Create Tools
ETHGlobal·Sun, Oct 9, 2022, 12:00 AM
Join Iain Nash of Zora for a talk titled, "ZORA’s Create Tools", 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] yeah up next we've got another awesome talk uh by another member of the zoroart team but ian um here with us to chat about uh create tools as max mentioned um they're gonna kind of go a little bit deeper uh into uh into what can be done with uh with all the tools that zora has so um without further ado i'll invite you to come up on the on to the stage here um and share his video share his audio do all those good things and i will also stop sharing my screen so you can take over as well um so whenever you're yeah thanks for the introduction jacob um yeah so what i'm going to talk about today is adding on new user interfaces for creating custom edition content types and how the zora drops tooling works for both the additions and the drops so the idea here is creating a zora drop contract with our creator factories and all the on-chain infrastructure and all you need to build is another front end so there's no solidity involved and this really just uses what solidity we've already deployed on jane and kind of how some of it works behind the scenes i'm just gonna make sure i have the chat open for you guys and start sharing my stream give me one second so we'll start off with some of the official zora documentation because it's a pretty great way to understand how our smart contracts work so if you go to smart contracts and then create an nft collection this does a pretty good overview of all the different nft contracts that are a part of our drop stooling the way the contracts are structured is there's a zora nft creator and it's a factory that creates the erc721 drop and it's a template nft contract that creates a new addition the idea with the erc721 drop is that the metadata that is generated from the drop contract is generic so an example of that is in for instance a addition you want to have the metadata pretty much the same except for just the edition id that changes however with a drop you want to go into a folder either on a server or on an ipfs or iweave instance and grab the specific token id because each different token is a completely unique artwork and those are the two main distinctions we actually have a repository open sourcing soon that provides more interesting renderer approaches one of them allows for products and redemptions one of them allows for creating groups of additions so if you have a hundred that want to be one to another hundred that want to be another so there are a lot of fun things you can do with that but it's solidity and i wanted to keep this talk really into how the javascript interface works so if we go to the zora nft creator here you can see these are the arguments for creating a contract and here there's a function to create an addition and a function to create a drop now this function does the creation in one go so a lot of things get done at once and we can break down a little bit more specifically how this works and what the javascript interface is in this create addition function so an interface you guys might be more familiar with that i'm going to jump to is the etherscan interface just to show how this is not really proprietary zora but it's just general web 3. we can have the create drop here that takes the name symbol admin edition size royalty bps all these different arguments we'll talk about in a little bit and then one for addition and then there's another one that's for uh generic stuff so this is if you're doing solidity extensions you can utilize that um going here so the first argument is the name it's the erc721 and ft standard we all know and love and it's actually for editions the name of the nft so if we go to test to create.zora.co we pick the zorogenesis hackathon nft and then we go to etherscan for that address you can see that the title here matches the title here and the metadata for the nft is informed by the contract title now one thing to think that's a little problematic with this is that typically indexers don't support changing the name in the symbol of an nft contract meaning that a lot of the stuff you can edit after the fact but name and symbol are two that you just can't really edit unfortunately next is the addition size edition size is interesting it is the maximum number that can be minted and this is a level of creating scarcity it's a useful way to sell nfts if i told somebody that they could buy a hundred and then i actually could have sold a thousand those hundred would be left worth less in some ways because they're more people willing to sell the same item if you set the addition size to one you're creating a one of one nft and this is actually a nice way to use these contracts if you want to just mint a bunch of specific nfts on a front end that are yours and they're not being sold in large amounts the other thing is we have a concept of open editions with this tooling and open editions is an addition that can be minted to any size but it has the ability to be closed so after the edition is closed so you open addition here the addition size is marked as the number that were minted in the sales period so this would be 18546 and then there could be no more minted after that point so it takes the full set possible number of mints from the ethereum blockchain and then shrinks it down to the number that are minted and there's a contract function to do that the next is royalty bps this is the on-chain royalties and bits per share and bps essentially is a hundredth of a percent so if you want one percent you put in a hundred if you want 10 you put in a thousand if you want 10.01 you put in a thousand and one the reason this is not just a percentage is that solidity doesn't support a decimal point and it's a pretty respected financial way of setting the percentage so you can see here i'm doing a 10 royalty that's a thousand bps a thing to do too is if you're unsure how this works you can just do bps from percent into google and you get a nice little calculator here um and a chart and there's some cacket yeah this calculator is quite nice so i can type in 10 it will give me the basis points continuing onward we have a default admin so the admin address is the address that manages the entire contract can do anything that the contract has ability to do funds recipient is the address that gets the funds now the reason these are split between two different addresses is if you wanted the funds recipient to be a split another way is if you wanted to fund juice box or you wanted to fund a dow from your nft sales or you wanted to put the funds to multisig but your personal wallet would manage the drop so it allows for some flexibility the next is sales config sales config is complex um we'll talk about that in a little bit this determines when the nft is for sale who is it allowed to be sold to how much it costs and all those sorts of things it's the arguments for the lazy knitting description it's a string that you can see in here it's just this string now one thing to note about descriptions for additions is that they're stored on chain and we can actually see that by going to by going to this contract here and then since there's a factory each nft is its own independent wholly owned contract and then i get to the met renderer and then i can ask for the information associated with that token and then boom we have this whole description stored on chain now it's stored on chain which means that the cost goes up with the more content that you put in the description the reason we didn't use off chain media for the description on additions is that it would require a server and zora is really trying to be decentralized and fully owned by the individuals that are creating the media and a great way of doing that is to put the as much data as possible in the contract that the nft ownership is held by and most people don't really mind the increased cost because this one description is used for tons of different nfts so it's pretty efficient in the end for instance this nft was minted 165 000 times so copying this description once for this many nfts totally makes sense if you're minting a thousand individual unique nfts with a thousand different descriptions that doesn't make any sense and then we have the animation uri and the image uri these are part of the erc 720 or the image uri is a part of the efc721 spec it defines the image shown for the nft in this case just this image and you can go down here in the zora interface and you can see that image url and this loads the full sized image animation is an extension that's pretty well accepted made by openc and it's used for any non-image content animation being web page audio video even 3d objects are supported in animation uri and this is kind of what we're going to be getting into with our little demo after this the demonstration project will create a web page using this animation uri field if we go down here's how you might call this in javascript we'll talk about the sales config in a minute but my essay so this is going to be my name symbol essay 10 it's an addition of 10.
so after 10 minutes there can be no more made it shuts down sales even me as an admin i can't increase that number 10. the only time you can change the edition size is when you do an open addition and then you close it so there's no way to increase the edition size there's only a way to decrease it really in a very specific case here we next have the royalty bps default admin funds recipient for small projects it's worth just setting to the address of the mentor so it's set to the address of the mentor here sales config you can pass in a default sales config and that'll just disable sales and then you can go ahead and use the zora create tools to set your sales settings or you can go and set a sale to start right when somebody mints it's really up to your use case here we have the ipfs urls now if you're familiar with you know typical http what is ips colon it's just a way to specify that the asset lives in the ipfs system rather than on the web http https you can totally replace these urls with http and https but it's not recommended because it's not a decentralized thing if your server goes away the nft image becomes broken but it's really up to you now we're going to talk a little bit about the sales configuration the sales configuration is one thing to notice is this is a solidity extension that takes in a different size compared to a full number full number and solidity is typically defined as 256 bits this clamps down those numbers quite a bit into 104 32 64 bits in order to save space and this saves deployment costs which saves you ether first is the public sales price it's in the number of ether and you're going to specify that to 10 to the 18th the easy way to get that is ifconverter.com so if i pass in one each it'll be one to the 10 to the 18th way and this is a wave field so you would put the way into your public sales price max sale purchase per address this is how many you can purchase per each address and if you set it to zero that means you get unlimited mints per address but let's say you only wanted one address to knit four or five so they couldn't buy up all of the nfts in one go or even just one you could set that to that number now the thing to be cautioned about or to be cos cationary about with this per address field is that somebody could always just spin up more addresses but it's a little bit annoying and it does slow people down so it can hopefully encourage people to have more unique buyers but you know it's very easy to get around if somebody wants to the public sales start is in uint64 and it's stored as a block timestamp so that is a unix time it's the number of seconds since 1970. if you want to get the current unix time you can just type unix time and duckduckgo and it'll tell you the current time i can do 20 22 0 2 0 2 t 12 0 0. um actually for drops what i typically use for unix time as well from alpha so if i go from alpha and i say unix time yesterday 12 pm um cet central east european time it will say convert yesterday um at 12 edt okay this is not working unix time 12 p.
m [Music] august 2nd cet so convert 12 pm cest august 2nd to you next time boom we get the time stamp right there and then we can just take that and put that into the contract it's a nice trick especially when you're dealing with drops across many different time zones to just quickly get that number for your sales start and sales end if you're building a ui you probably will use some sort of calendar so it's not a big deal if you don't want to start with a public sale or a private sale that's a pre-sale you can just set the value of all of these time stamps to zero if a sale starts at the beginning of time and ends at the beginning of time it never happened pre-sale start so pre-sale is determined by this merkle route the merkle route is a predefined way of determining all of these different users if they exist within the set and if a mint matches the merkle root then it can be minted under pre-sale and the merkle root includes the variables for sale price and max purchase per address and address so there's no settings for that in the contract it's taken directly from the merkle root if you're not using the merkle root it's safe to set a merkle root of zeros and the reason you choose zeros as opposed to anything else is that zeros are cheaper to store on the blockchain so when you're making an empty merkle root just set it to be a bunch of zeros don't choose something like eeee or nnn like it's it's all the same thing as zero the chances that there's a valid merkle root resolving to that is basically zero so you wouldn't have that concern but the concern you would have is just saving storage space and this is how you would import a type and typescript from the xorolabs nft drops contracts package so you don't have to manually check every field you can have typescript check it for you as well and we'll get to what that looks like in the example the docs links are here and then i can share the slides in the chat okay let's go through some code so i made a little demo project for this that allows you to mint markdown essays with the zora edition tool and we can actually take a little a look at the current version at this link here it's hackathon quality code so don't judge me too much jacob are people able to see the chat and i believe there's one environment variable this mentor needs to set up so i'm going to go and set that really quickly and show you how it works okay i don't really have great ideas for this essay but um i can give you a quick demo on my localhost so let's do that and then i'm actually going to take some of my presentation code and put it in the markdown editor a markdown you can do this to create a code block and then we can add a header and then we can add another section for sales configuration and i've already connected my wallet to the website so you can see i'm on the rinkebee test network and i'm connected to this website and we can add in the sales configuration slide and then i'm also going to add in a github repo and let's make the link pretty so here i can just take this github repo oops i deleted it there and i want to make it a link and if we look at the preview this is wrong think it goes the other way gotta love mark down yep and then we just delete this line here and then i can go ahead and publish so here it's posting to my local server to the publish route and then the publish route is returning a response here with the sac id and the image cid and if we take a look and see what these are this should be an html web page of the essay i just wrote so looks good to me create an edition there's some code and you can take take a look here and this is the rendered html from that markdown editor and it says publishing so if i go over here there's a contract interaction and i can go ahead and take a look at the hex data for it and if i turn this into uh we can just see if this works i've never gotten the metamask data parser to work all right it doesn't work we will confirm the transaction it went through and then the easiest way to determine where the new drop address is is to look at the events on etherscan and you're going to do the same thing in javascript we can actually add that in if there's a little bit of time because right now it does nothing it should redirect to a page where you can view your essay when you're done making your essay and create drop the second address would be the addition contract address this is our new contract we just made and if we look at the contract we can do read see i think i need to set it as a proxy and we can take a look at our name um of the token and the descriptions that would be in name metabolism and then there's no description but we can then go over to our metadata tool to pull out the description the metadata contract is generic across each of these editions which means that you pass in as an argument your contract address and it'll give you your information so we have our description creating a drop presentation looks great we have an image uri so if we go to zora ipfs and we look at that image boom that's exactly what we just saw and then our animation see if this works yep okay so what does this look like on openc well we can take a look after we meant something so since i'm currently the admin of the drop i am going to mint myself a nft i made myself two we can pull this edition up on our test net view the right address let's see okay this did come through maybe it takes a few minutes maybe let's see and then the mints get went through perfect and then right here we have our essay metabolism this is the image is used as the preview that's why we have to create an svg you could also upgrade this to allow somebody to upload a preview image and then i open up the essay and boom i have the essay here something to note is in the sandbox view github will not allow blah blah so i need to go and open the site in a new window but yeah you can render markdown you can add some styling you could even add themes in the editor so if you were to go to this here you could choose the theme and then it would update this preview over here and then that same theme would apply to the site right here and you can actually fork this and do whatever you wish with it and there's a nice little uh gui editor here for those that like that something to note is if you link in an image it should work but it would be best to link in an image from something like ipfs and you might have to go and work with your favorite markdown editor to add that option in now that i've created this edition though and i can see on an open c which is awesome and i can actually probably see it soon on the create tool i think it's just cached let's see nope how would we view this information locally and actually let's back up a bit and go through how does this upload flow work and how is this app working behind the scenes the main page here is the create page and the sale starts off at zero and ends in one week and the reason is seven let's start 60 so it's seconds seconds minute then 60 minutes in an hour and then 24 hours in a day and then seven hours in seven days in a week so this sets the sale to last a week disables pre-sale that's 100 purchases per address and a 0.1 each sales price can go ahead and see that works by going to our drop and calling purchase purchase 0.1 i want one of them nope that'll fail one that's successful and then this is all pretty standard react so this here is used to disable the button when publishing here is content for essay title and description and then this is stuff with wagne which is a hooks library for interacting with ethereum and then this allows us to connect azure contracts with wagney here we have a fairly simple form it takes in a title description an essay i'm using a third-party markdown editor it acts in react just as a standard text input and then a button for publishing i decided to use the g-gen tool kit but you can use any type of front-end or your own component library to build out the components when you push the upload button the first thing that happens is it sets the publishing to true and then it gets the essay html from the editor preview it's a bit hacky but it works i didn't really want to re-render myself and then it calls api publish now a lot of times you might think why doesn't it just call pinata right here well two reasons one is mainly for security i don't want to expose my pinata uri and then two it's just a little bit easier to get those api calls done on the server you can batch it into one request and add in better error handling on the client and you can also render things on the server side the response then comes back as json we grab the ipfs hash from both the image and the essay this is just for debugging and then it calls contract.create edition the abi is pulled in from the node package of the zora contracts all the zora contracts have node packages with type chain and apis published and you can take a look and see what that syntax is in the node modules package it's a pretty easy way you're not going to find it directly in the repo since it's compiled automatically down but you have deployments folder and you can choose the specific version of the deployment you want to use in your application this folder which includes the artifacts now these are the json files with the apis in them and also type chain and these are typescript definitions and javascript files interact directly there was a conflict between the markdown editor and our type chain builds so i was not able to use type chain with this project and i just instead used the direct abi files you can take a little bit of a look into how the api works i found pinata publishing from a string to be quite annoying but this seems to be working pretty well this is a very simple html webpage given the essay content and the title it just spits out a webpage could probably improve on this quite a bit then i'm doing a request to pinata directly i'm not using any of pinata's tooling i'm just doing a standard http request so i set the cid version i added the type essay from pizza metadata not necessary but nice when you're in the dashboard it'll show all the essay types in one section and then i'm just using the isomorphic fetch library which i believe is included as a part of the next.js framework to then send the response to pinata with the form data now the reason you would use form data is to allow for adding on a file json can't really encapsulate files very well so solution here is to just append a file onto the request and then it splits it up into multiple chunks for you and you don't have to do anything for that it's all automatic passing an authorization header so this is coming in from next js as the pinata key and then it calls the hd response and then returns json probably needs to have better error handling but this is the r upload to pinata function short and sweet then this is the handler this is the next js function that gets executed when this api route is called first it checks that the request is a post it's going or get requests and then it parses the json body to grab the title description and essay fields and you can see that we pass those in right here json stringify image cid so this just uploads to pinata a function make svg card with the title and description the content type s html make html page same as making svg card it's just here the make svg card is used both the same on the server and the client so it's in another file and i exported an svg from illustrator and threw in the text that's why the scaling is a bit weird it's probably better to manually write your svg but time the next step is to upload depending on the essay and then i just returned the image and the sac id and the cid is the content id field it describes the file on ipfs so when your url looks like ips colon slash this is where the cid is put if you're addressing a folder you just add the folder after that and a bunch of files can fit into the id but these are just simple cids that include only one file directly there's no folders involved here this is a bit of a hack to create our symbol field you can take a look at that here so the symbol of the nft drink bee fresh here now it knows so three metabolism i don't know why metta got removed oh substring one through ten it should be substring zero through ten maybe eight so it just takes the first eight uppercase letters that are a through z zero through nine um and makes that the symbol and you can see our purchase went through here and let's see if it shows up on the zorg creator testnet should at this point yep it's doing something there we go metabolism 22 hackathon creating a drop presentation and right here is the mint button and then here's the treasury so i can run a withdrawal here now i want a better preview page than this so now that we've covered how the upload works and how the cid is then added to how the cid is added we can then now look at how we retrieve this published contract so if i go to additions id i wrote a web page that does a call using use contract reads and has an index page so if we go to editions slash edition i want let's see what happens loading loading right there metabolism 22 creating a drop presentation and then we got our ipfs another ipfs so let's do this data it would be data [Music] zero one and two zero one two so data and then our data field and we know data's got to exist so now we can do title image sa equals data and then we can return header heading title one make it real big we can embed the web page since this is a full web page i'll just pass an iframe source pass replace this with an http gateway this is all react-y stuff maybe we swap the image and the essay there we go create an empty edition and then it looks like there was an issue loading the essay um not sure what's happening there but i think that's time so to play with this repo and to continue on you can take a look at how all this works in the code in my github just mark this down and i will publish the latest changes to github ian zora sa edition mentor thank you so much and i hope somebody makes some cool weird p5js html interactive sdg generative i don't know there's some really cool things you can do with this so have a good rest of your day amazing thank you so much that was uh that was sick i think it was just being able to go through all that in one fell swoop and uh wow that's awesome yeah i think that's going to be an amazing resource for people as they build over the next weekend um thank you so much for taking the time to roll for that with us really appreciate it you
Automatic transcript — names and jargon may be misspelled.