How to create on-chain NFTs

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what if i told you that we can create a collection that's purely on chain what do i mean by that no ipfs no external servers all this content they are svgs and they live on the blockchain if you want to learn how to do this stick with this video and watch it till the end and you won't be disappointed [Music] [Applause] hey how's it going guys my name's daniel aka hashlips and welcome to the channel where i teach you how to code and do fun things on the blockchain in today's video like i said we are going to be teaching you how to create on-chain nfts up until this point i've shown you through various videos how to make nft collections upload them to a server or ipfs write a smart contract and then link them up together in this video i'm going to show you how to do the exact same thing the only thing that will be different is that there would be no ipfs because the content is going to be generated on the smart contract itself now before we get started i would like to say thank you to the ten thousand people who have subscribed to this channel if you're not a part of the hashish family yet go ahead and do so subscribe and like this video because i promise you you will get some value out of it then if you get stuck in any way as always go ahead and go to our discord channel and our telegram page you can find these channels by going to the hashtabs.online website and finding the social medias over there or simply on youtube up at the top corner over there that's all you need to know before we start and now let's get going so in order for you to fully understand what we are going to be doing let's start by looking at the differences between on-chain and off-chain nfts first of all what is an nft basically an nft is something living on a smart contract a numeric value that is assigned to someone's address and controlled by a contract living on the blockchain it's very simple as you look at these videos that i put out you'll start to realize exactly how simple this concept actually is but basically in layman's terms if people refer to an nft that they own they simply own a piece of the smart contract or a numeric value that's assigned to the address for instance if you look at the nerdy code of clones collections these are a great example of off chain nfts because the images themselves and the metadata lives off the block chain that's what it means now if you look at these nfts let's look at number 34 all right 34 is a cool looking nft and you can see there's its number and if we click on this nft it looks pretty cool and someone is owning it right so this token is owning it that's the owner of this nft now on the smart contract the smart contract knows that this person whoever whose ever wallet it is is connected to this nft and how do we know that well if we go to the details page we can click on the contract address over there and this will open polygon scan if this is on the polygon network or ether scan if it's on the ethereum network now let's go down and see what happens if we go ahead and we click on the contract now that we are on the contract section we can see there's a read and a write contract this is basically how we interact with a smart contract and polygon scan ether scan they both give us very nice reusable kind of interfaces to interact with different contracts now we are pointing to the nerdy coder clones contract so let's go and look for the function down here where it says token uri there it is so now if i enter the token 34 in there and i query this you will see it thinks a bit and then it goes and spits out ipfs with this cid and a 34.json if i go ahead and copy this and go into my browser and find an ipfs portal or a gateway so to say and query this we will actually be seeing the metadata off chain let's go do this now you can see i've taken this part everything from the qm of the cid up until the 34.json and i attached a gateway which is the ipfs gateway to it and what happens this is basically what openc does in the back when it's reading your nfts it gets to the meta data now this metadata lives on ipfs and yes it's decentralized so it's technically on some kind of blockchain right um but it's not on our contract it's sitting outside of our contract the same goes for this image if i go and copy everything from there to the end and replace this with our gateway we should be able to get to that image and that's what i'm talking about when i say off chain data the data simply lives off the actual contract it does not sit in the polygon network it does not live on this contract address the only thing that lives on it is the actual logic that keeps track of who owns what nft by referring to the numeric value that a person owns i hope that is clear now let's take a look at unchained nfts looking at unchained nfts avastars is a perfect collection to take a look at the reason is because avastars are on chain meaning that the data that you are seeing is rendered on the blockchain how cool is that now the smart contract of avastars are quite complex and since then you know unchained nfts have been experimental so these guys have really done a great job watching my previous video where you can actually clone any smart contract you can dig in deeper and take a look at how avastars have made their collection but i think it's really amazing considering that these are all nfts generated purely on the blockchain so you can take today's tutorial what i'm going to show you and then adapt it experiment explore and i'm sure we'll get we are going to make consecutive videos where we take this concept even further now what is a common amongst all unchained kind of nfts is they almost always use svg as images what is an svg well svgs are scalable vector graphics they not like pngs or jpegs whereas jpegs or pngs are rasterized images they are based on pixels svgs in simple terms are worked out by math that's why if you look at the collection like avistars they look very clean they look sharp if we click on one as you can see the image is super clear now even if you were to zoom into this image a million times it would still be super clear and not pixelate why is that the reason is it's worked out by mathematical equations to kind of work out the shapes and the curves you know and the beziers in order for you to see a crystal clear image what does this mean for blockchain well because these images are mostly constructed out of code and maths we can simply add that into a string on the blockchain maybe wrap it around a base64 which is a nice encoded data structure so that we can send it over the protocols easily and then it can display on the other side on anyone's browser because the browser knows how to render this image let me just show you how the data of an svg looks like let's briefly jump over to the svg online editor now you can go ahead and go to this editor if you want to and try this out we are indeed going to use what we create here as a base example for this project that we are doing now if you want to do something more complex you can use illustrator which is a great tool but for brevity's sake and also for this tutorial so that everyone can follow along i'm going to stick with this program so if you are going to create complex shapes in illustrator or any svg program keep in mind that the bigger the code of the svg becomes the more gas it's going to take because you need to save all that data on the blockchain so that's why people have found smart ways around this to keep the data small and change values inside the svg code to make it look different i'll show you what i mean when we get to the code of this svg but for now let's use this as our example i'm going to create a cube at the back and give it this green color it's going to have a width and a height of 500 which you can change over there then i am going to add some text you can just click on this text icon and put some text in there i also just positioned it but an easy way is to just click on these two icons over here it will center it now for me to see the code of this svg i have to go and save it so i'm going to click on file save image and there it is i'm going to drag it on my desktop and then open visual studio code after that i'm simply going to drag the svg on here to quickly see what it's made up of now an svg always starts with a svg and then ends with an svg closing tag now the opening tag over here you can just see it specify some standards you can read more up on svgs and we'll elaborate on how these svgs are built up and what you can change to make it really look cool but basically it has an opening and a closing tag and the content inside varies and changes you can see that there's our rect which is the green box that we placed in then on top of the green box there's our text and you can see that it kind of transforms and position it some way it makes the font weight it also sends sets the font family now these are all attributes of this font which we can mainly get rid of most of it we want to keep the data as small as possible but still have a viable svg that will render on the browser so how does the browser know how to render this data well it's simple if i double click on my svg you can see it simply opens it the browser exactly knows how to display svg data because it is in tags and it knows how to handle it and it's pretty fine to just use it like that but seeing that we need to kind of send our svg through the url in some way to the front of the application from a blockchain app how do we do that now something that is a concept that we are going to have to grasp is not only svgs but base64 encoding think about it like this and i don't want you to get overwhelmed because it's very simple these concepts when we send data over a protocol a protocol is usually something like an http protocol where you usually type in here google.com all right when you do that it calls a pro over the http protocol and it fetches data in little packets now the internet knows how to handle certain packets and certain kind of encoded strings and characters now in an svg format sometimes they might be characters that might break or that might mess up the protocols rules okay that's why people usually convert or encode it to base64 base64 is an encoder and you can also decode it again so what happens is we need to wrap a base64 wrapper so to say around the svg first before we can then put it in our url and then once we do that when we query it on the browser it will decode it and we can see it on the browser itself i hope that makes sense i know we will get into these concepts more in depth but for now just understand for us to send the svg over a protocol it's best to wrap it around a base64 aka encoding it now you don't only encode svgs you can encode numerous things with base64 okay so text files other images and so on let me go ahead and see how can we encode our svg over here and make sure that we can render it by calling it in the browser i'm going to head over to the simple website where it says svg to base64 now we are going to do this with a more manual process when we get to coding this in the smart contract but for now i'm going to click on upload image and then on my desktop i'm going to select my svg you can now see that this image have been converted into base64 data this is the base64 string in itself and this is our actual svg but how do we tell the browser if we put it in our url tab over here at the top that it should render an svg well you see this part here below this is kind of its rule about what it needs to render so i'm going to try and copy everything from data and then go all the way to the back including that plus it's very difficult to select i'm going to do that again oh what the heck i'm going to select everything then i'm going to open a new browser tab i'm going to take out all those things in the at the end and let me take everything out in the beginning from there so all i'm left with is this data image svg saying what type it is and then obviously base64 the encoded part and then the actual data now when i press enter you can see that it renders the exact same image maybe this is not clear enough so i'm going to go back to the website that we were on and i'm just going to paste it here as well and there you can see that the browser actually renders this image based on this data string that is it and that is svg's and that is how cool it is and that is why we can basically use this as unchained data being i can say assembled on the blockchain and pushed back when we query it off the blockchain okay of the smart contract so i hope now that the theory part kind of is done we can jump in and get our hands dirty by jumping into the code and actually implementing this in a smart contract another example of a purely svg based collection is the ancor certificates basically so the anchor certificates are svg based nfts and they look like this they look pretty cool and if i click on one you can see that this is an svg and the colors change on chain basically on the blockchain itself so if we go to the details page and we copy this token id which is quite long usually it's just one two three four five six and so on but this is a long id i can go to the contract address by clicking on the contract address itself and this should take us to ether scan and once we're in etherscan we can click on the contract on the contract section under the read contract these methods allow us to read remember if we go to the token uri and we now paste in that long id that we just copied and we select query this will actually give us the base 64 representation of the json now the json remember is needed for openc to identify a name description and the image so within this base64 lies another base64 which is the svg let me show you what i mean by default either scan can't you know put commas it puts a new line for comma so what you need to do is copy everything from data all the way down make sure you have everything go to visual studio maybe open a new file and paste everything in there once we have everything in i'm just going to go to the very start and take out this space and give it a comma that's just something that ether scan does which is quite annoying but we can get around it now i'm simply going to paste this in the url and hit enter here you can see we've got the metadata json so we've got the name we've got a description and an image and the image is actually base64 and there you can see this time it's image image svg so i'm going to copy the data all the way to there once i have that i'm going to replace that in the ur url and press enter and there's the actual certificate that this um nft consists of now this is all rendered live and i hope you guys understand how cool this is at this stage and i hope you're excited that we are going to do the exact same now why i wanted to show you this collection is because this is um mostly what we will be doing and our collection is going to be an image and we're going to have text on it just to keep it simple but you are more than welcome to dive through these collections and check how their contracts are set up and try new things out in the future videos i will see how we can adapt this code and create something like avistar or maybe even better anyway let's get going let's dive into the code let's start off by going to the main hashtabs getup page and there are numerous repositories here things that we have worked on on the youtube journey so if you find something interesting like you want to know how to do art generative code and so on go and watch the rest of our videos and i'm sure you're going to find it very interesting the repository that we want to work with today is in the repository section so you can click over there and then simply scroll through this list it might not always be at the top but it's the solidity smart contract repo if you click on it it's not really a repository that is pretty uh and laid out in detail with readme files it's simply a place for me to just drop files for you guys to go and grab so please don't mind the structure of this but the file that you want to focus on is the nft on chain once you go to the nft on chain what you'll see there are these three files now before i start i would just like to say that the base60 base60 encoded library.sol was not created by me it was created by this developer um brecht brecht devos am i saying it correctly brecht devos and thank you so much for creating this lovely library that we are going to be using today anyway jump back to the three files that you've seen over there and click on the nft underscore start if you want to follow along if you simply want the end code you can just go to that file but follow along and i promise you the more you code along with me the better you'll understand what you're doing and you're going to be feeling much more confident when entering the blockchain space as a developer and you'll know what's happening alright next what you want to do is simply copy this code by clicking on that icon the reason why you want to copy this and a lot of people would recognize this code right off the bat this is the simple nft contract now i'm going to start off by using the simple nft contract and the reason for that is we're going to strip it naked so that we can actually have a holistic view of how to create this on-chain nft data from scratch but we need a base to start from and what better base than using the pure nft contract that we use for everything else so that's why i'm going to use it so copy everything and head over to remix so once you're on remix.ethereum.org which is a brilliant code compiler for solidity by the way and go and check out the rest of the videos to clearly understand how this works but you can follow along by simply creating a new workspace click on this plus icon and i'm just gonna call it the default workspace it is fine next in the contract section i'm going to right click and say new file and this time let's maybe just call this the on chain nft like so dot sol so this is going to be the unchain nft.sol and going to paste everything in here to this file now once i've done that you'll see that all the dependencies start popping in that's because we have the two dependencies from open zeppelin which is the erc 721 and the ownable contract now we are going to need that beautiful base 64 library that was talking about so let's go ahead and create a new file for that as well and let's call it base64.sol once we have that we need to go ahead and jump back to our code go to the unchained nft click on base64 and copy everything in this contract head back to remix and paste it in there all right once you've done that you should see a green tick meaning that you've done everything correctly this looks good and now what we can do is i'm going to remove this storage the owner and the ballot so i'm just going to delete those smart contracts because we really don't need them and maybe i'm also going to delete the artifacts because that gets generated as well as close down all these folders i want to focus on these two nft contracts well the one nft and the one library so next what we need to do is go to the unchain nft and at the top here we need to import our base64 now how you do an import is you say import with quotations and we need to locate the file this file is sitting in the directory that this file is in so you can simply say dot forward slash and then base 64.sol once you've done that you need to end it with a semicolon and this will now import this library next let's rename our nft to kind of match our description of the of our name so i'm also going to say this is going to be the on chain nft like so the reason why i name my contract and the name of the file the same is to keep track of them you'll see when you get to the deployment section and you need to select a smart contract you can see that it has the file name as well as the contract name it just makes sense to call it like that you can even see that the base64 also follows this convention as well as all the other contracts as well so that's just convention so keep on doing that and you'll be a better solidity programmer but let's jump back to our nft contract and let's see what this is all about now currently we've just imported the base library but we're not using it we need to start now making use of this library and also strip out this nft contract of all its extra bits and features because most of the stuff we're not going to need especially the fact that we point to a base uri the fact that we have an extension the not revealed i'm going to strip out almost everything just to have a bare contract and that we don't have too much moving parts and just focus on the peer on chain data part so just to give you a brief overview of what this contract does before we rip it apart if you go to the virtual machine engine and if you go and select your nft contract then on the deploy section for the constructor arguments i'm just simply going to enter test maybe test in all caps and then at this point this is where we usually put the https um forward slash or the ipfs you know links so i'm just going to leave these empty like this and say transact and it's done and then here at the bottom i can see the contract now usually how it works is i can mint let me min 2 of nfts i can look and there's the total supply now when i go and select one for the token uri or pass in id2 doesn't matter those nfts exist i can see that i get my ipfs link back that are specified in the constructor and this usually links to off-chain data which pulls back metadata that contains an image now our goal is to not have that and to completely have the nft on chain so let's go ahead and clean up this contract so first things first we most probably don't need this base uri anymore i'm gonna hit command f and on pc i think it's control f or something but anyway go and search for the base uri and where it's being used so i can see that we have a function over here set base uri i'm going to take that out then go up to the top where it's being used so this kind of returns our token uri i'm actually going to go ahead and clear out everything up until this point and just keep my bracket in there so it doesn't break but basically what this is going to do it still needs to check if this token is valid but the logic that's going to go in here is quite different and as you know remix struggles with formatting so i just need to format that correctly perfect then let's look if there's more instances so there we have the base uri function that reveals it i'm going to go ahead and remove that i'm going to go ahead and remove that one also over there and at the top next next is our base extension so we can also go ahead and remove that function that sets the base extension same with removing it over there and that's it the cost is interesting so what i want to do is instead of putting it as a parameter because i'm going to take this as we don't want to change this so i'm going to search for where cost is and cost is basically being used over here as a function i'm not i'm going to take this out so you can't set the the cost you have to set it when the smart contract starts i'm going to replace the cost over there with the actual 0.05 ether i'm going to maybe make it 0.005 ether and then we're going to go up to cost and we're going to remove it completely i just want to get rid of a bunch of variables and just show you that a smart contract it doesn't really have to be this complex and up upgradable and yes there is a trade-off from having everything upgradable but remember it's also good to have something that cannot change on the blockchain because that also creates more trust within a smart contract for instance if the owner can't mess around with the function some so much it does create more trust also it can create errors if you're not sure what you're doing so make sure that everything is perfect before you deploy let's go ahead and remove some more variables so let's go ahead and get rid of the rest of the stuff well we can't get rid of the max supply but we can move it somewhere else so let's see where it's being used so the max applies being used over here and we'll replace it over there for now that is the only place where it's actually being used so we can just get rid of it see that's why i want to get rid of the variables because a variable is only really useful if it is configurable first of all and if it's being used on multiple places so some of these are just configured once and only once and we might as well just put it where it's being used let's go and check the max amount because the thing is with this max amount contract i'm going to i'm going to take out the functionality that we can loop over and mint as many as we want to we are going to make this smart contract so that we can mint one at a time and that way we can also handle the random functionality a bit better down the line so let's go and have a look at where this shows up and it's being used here as well so i'm going to take out that functionality i'm going to take out this functionality and also here and that's about all the places it's being used i'm going to do the same with the paused so the paused is necessary to pause the contract but we are going to run this contract and then just have people mint on the fly and we're not going to pause this contract so let's go up and take this out as well then the reveal obviously you can also leave this in but for this purpose of our tutorial we're not going to need it so i just want to make sure that we remove it on the right places so there's the reveal function where we can set the uri we can also remove this reveal and we can keep the withdrawal because that's quite important especially if there's going to be ether coming into the contract next we can take out this where we set the base uri and also the part where we set it over there now we do not need to pass in the name and the symbol as constructor arguments instead i'm going to change it so that we directly put them on the smart contract so let's call this on chain uh nft like so and for the symbol i'm going to make this o c n like that okay now i can get rid of these two constructor arguments and we have a very clean constructor next i can also get rid of this reveal if it's not being used anywhere else and this one and it's also not being used so we can get rid of these two variables so at the moment we have a very clean contract and like i said we want to change this so that it can only mint one at a time so let's get rid of this argument to say that we can mint as many as we want to and we have to take down this mint amount we also have to say that if the supply plus 1 is less or equal to our max amount that's fine we're going to leave this clause in there but we do have to take out this times by the by the amount that's going to get minted and then we can get rid of this for loop let's just format this a bit better like so and then instead of saying supply plus i we're going to say supply plus one so what's happening here a mint function just mints an nft onto the smart contract assigning usually an owner so basically we call the mint it's going to check the current supply that's in the contract it's going to make sure that the supply plus one if we're going to mint one is indeed less or equal to the max amount that this contract should handle then it's going to skip the payment if this is the owner but if it isn't then it's going to ask for this fee to um complete its mint and then we're going to mint here using this underlying statement from the erc721 contract now we're going to call it on the message.sender as well as call the supply plus one and that's all that's basically happening there for this function of querying the wallet of the owner we can also get rid of that it's just going to get in the way and clutter our contract and that's basically it i want to show you guys how simple a smart contract can truly be now even though this doesn't work yet i am going to just say return a string so they just return an empty string like so just so that it doesn't moan anymore but this smart contract is about 60 lines and including this big disclaimer if we take this out you'll see that it's about 40 lines long i'll leave this disclaimer in the smart contract so that people understand when using it that they are using code that's been written for a tutorial and not really for production but you can use some of this for production just be aware that you need to review it yourself and that i'm not liable if something goes wrong anyway but it's now a very small smart contract and we can still deploy it so if we call it you can see this time we don't need to deploy with arguments because we've placed everything we need inside the constructor itself on the contract so if we hit deploy it's on the blockchain so now once we have it we can click mint we can click mint a few times so you can see it's successful we also don't have to specify now how many we want to mint because it's only going to mint one at a time we have all the features that we had before like who's the owner what's the symbol the name as well as the token uri which won't be anything because we are returning an empty string let's now go in and adapt this to actually work with our concept of our svg that we want to return now as you can remember we did make a svg image which is this one and we want to go ahead and return this from our smart contract directly when someone calls the token uri function but now how do we return that well remember that we also got the code for that svg over here and now we have to follow a process of cleaning it up let's get rid of a few things for instance this g tag we don't need that to wrap our element because that is just a a kind of a structure of svg to tell it how to render but we can get away with not having that we can also get rid of this title this layer one as well as the id tags in each one of these rectangle and the text item so the text also has one it's just sitting here at the back so we can remove that one as well let's go ahead and remove the stroke of this text while we're here as well as a few other things such as stroke with make sure you remove the complete attribute and not only part of it then what i want to do is this i want to change into middle now we could have probably done this on the on the editor when we created this but i just want to take this out it's not really necessary at all i can also go and go ahead and take out this space this preserve space the font weight i'm gonna take away the font family i'm really going to strip this down quite a bit because i really want this to be minimal when it exports from the blockchain so let's also take away this transform now i really want to center this text and currently we have an x and y position on our on our attribute but this x and y is specifically said to be at a at a dot position if i can put it like that but we want to change it to be maybe 50 percent of the y and then also 50 for the x so let's go ahead and do that now we have a clear looking text field so it is going to be anchored in the middle but there's also something that we can do to make it truly be in the middle middle uh which is the i think it's called the dominant uh bass line so the dominant bass line looks like this and if you set the dominant bass line to middle as well then you truly get a centered text image because the dominant baseline changes the base of the the baseline of text and if you know about code text always has this baseline the line that it starts off and draws on so if we center that we center the text anchor to middle we make it fifty percent um y fifty percent x we should really have a centered image or centered text at least on top of our image okay so what is next we have our cleaned out svg you can see that we only using minimal things we can still maybe get rid of this stroke we have minimal things that we can work with and this will actually still show up as an svg so i want you to now go ahead make sure that you've cleaned out the svg and go back to the program we over here and what i'm going to do is create a function so let me create a function and call this bold image and this function is going to take eventually a token id but for now i'm just going to maybe make it public view so that we can return and it's going to return so we have to say returns string and the string that it's going to return is type and memory because it's temporary remember so if you don't know solidity too well go and watch my solidity basics course you will learn quite a bit next we actually want to return a string now you can't just return a string a one line a string while you can we can say return just a string like that and this would be fine and we can add some stuff in there and if we do we probably don't have to have this as view we can make this pier that's why this is telling us that we can make it pure because it's not interacting with anything in the smart contract but currently we don't want it to do that we wanted to return the svg image so how can we return this svg image well let's see how can we concatenate strings when i talk about concatenation i'm talking about how to add different lines into one line so that it can be rendered there's a library in solidity that we can use which basically is called abi dot encoded packet okay abi encoded packet all it basically does is it concatenates strings so you can concatenate hello and then let's say a world like so maybe make a space as well so let's put an extra comma in there and let's make it concatenate a space like so but this i believe returns uh bytes which we need to convert so we need we can't just return this because our function needs to return a string so let's see why this is complaining so returning arguments type bytes memory is not explicitly convertible to type variable string that's fine so all we have to do is type cast it so what we can do is we can say this should be a string like so and when we wrap this you can see that we are now converting this function into string and i'm just going to um render this so you can see i'm going to turn this to pure just so that the compiler doesn't moan and then i'm going to redeploy the contract once i've selected the contract down here i can just simply say deploy when i go and look at my contract i can mint one and then when looking at the total supply we have one that we can check up on so enter that one id into the token uri which is this function that we have just worked on okay but we actually want this bolt image function okay so token your eye will still return empty but you'll see that our build image function is there so if we click on the build image functional you can see it returns hello world and it concatenated the two words okay and that's exactly what we want now we don't want to return hello world the whole time we actually want to return the actual svg so now let's see how we can do that i'm going to take out everything in this abi encoded part going to open it up and this time i'm going to make use of a single quotation marks the reason for that is if i have a string with double quotation marks inside like our svg images where they have double quotation marks for the attributes it's not going to work if i use double quotation marks so you can use either double or single depending on your use case so the outside ones are going to be single quotes and then inside i'm going to paste this then i'm going to put a comma and make a space put another two quotation marks and so on so i'm just going to carry on doing a few so i can make use of it the last one doesn't get a comma so let's go and copy over all of our content so i'm going to copy this i'm going to head over back here i'm gonna paste the next line and i want to copy this line i'm gonna go back paste that in and then simply the last thing we need is the svg so we can just say svg like that that's just the closing tag and that's the same as that okay so now that we have this we should actually get our svg returned so again i'm going to save this i'm going to redeploy the contract so i'm going to make sure i'm on the contract deploy it then mint 1 and then click on the bold image and you can see there's our svg and this is now being returned on actual um the actual smart contract it's unchained data that's being returned now like i said we can't just put this and copy it and put it for instance in our url that's not going to work it won't work because the browser will not know how to pass the data in order to do that we have to make use of our library which is the base64 that this developer was so kind enough to to create all right so we are just going to simply use the base64 um all it does is it encodes the data and the characters in a certain way all right but you can read through this it's very intuitive how this is done but i think this is on a much higher level that i don't want to complicate things with so just basically make use of it now you can see that this is a library in solidity and it is base64 and it has a function called encode so we can go back to our smart contract now and we can go make use of it let's briefly see what the encode function returns you can see that the code function returns a string as well so that is perfect for our build image function so let's encode all of this data so what we can do is we simply have to wrap this so we can say base64 because we have imported this at the top here remember so we can say base64 dot encode and then we just simply put brackets and we ended over here with another bracket now it is complaining because why if we go into the base64 we can see that this takes in bytes now we currently have cast this to a string remember over there now all we have to do is convert this to bytes like so so that the base64 encode function can take this work with it and then spit out a new string and that's all if we save this we can now go ahead again and run the program so let's go and select on chain let's maybe delete this one let's deploy it let's go ahead and mint one and then we can go and click on build image now this takes a bit of time it takes a bit longer because it has to run through the data replace things and it's very cool how it works but that's why it takes some time when you call the function but this is our base 64 data keep in mind this is only the data piece and not the piece that we fully need i'm going to explain to you what i mean when i say that how can we make use of this data base64 string go ahead and copy it all and i'll show you how you can use it inside the browser currently this is just the encoded string and please keep out the string path over there this is just a remix adding it go to your visual studio code and we're going to type something out to make it easy for us to understand now whenever you type in the keyword data colon in your browser url you are telling the browser that it's about to accept some data after the colon it asks what type of data now you can have different data types and we would have something like is json data at the end of the day in a few different kind of forms but for now we want to say that we are going to be passing an image forward slash svg okay then plus xml this combination with a semicolon at the end tells the browser that it's about to accept some kind of data we then go ahead and type in base64 to tell the browser what encode encoded kind of mechanism was used so that it can decode it then we put a comma which is very important and then we paste that string now if you take this and if we've done this correctly if we copy this all we can go ahead and go to the browser and by simply replacing everything here at the top and clicking enter we should see our image now i don't know about you guys but this is probably the coolest thing ever it means that our image is technically this long string of base 64 encoded data and by giving the browser this it knows how to render it now like i said you would also have different sorts of data fields later on we would also make use not only of the svg tate data type but also the the application forward slash json one so the application um forward slash json field tells us that we are going to be passing json and remember that we also need json for openc to read our data correctly and exactly that's why we want to use it like that so i hope you enjoying this tutorial this far it's going to get more intense now and it's very cool so stick around and let's finish off the smart contract so now that we have everything ready we have our build image function that will split out an svg which is going to be the same by the way every time if we don't change the parameters so we are going to have to change the parameters after this but let's just get the base structure down and see what we will actually need to render now in order for us to render an image on openc they require a certain structure of meta data so to say so we're going to follow the exact kind of way by exporting a string remember we need to or return a string when someone calls this function so i'm going to type in string because we know it's going to be a string then inside of this string brackets i'm again going to type in abi dot encode packet all right then i'm going to open my brackets and then in here we actually going to open it downwards so that we can add our quotation marks in the quotation marks like i said this is going to have to be base64 extension so because this is json data let's go and copy this string that we've typed out and then let's head back and paste it as our first part that we want to concatenate next what we want to do so i have to add a comma and then next what we want to do is say we want to base 64. so base64 the library dot in code we want to encode something so let's go and open and close these brackets like so and now i'm just i'm just maybe going to close this off as well like that and in here we need to abi encode it again because the thing is we need to pass this in bytes remember we we had bytes over there so we first going to put bytes like so open and close the brackets and then inside the bytes we're going to say abi dot encode encoded packets with more brackets now i know this sounds confusing but we need to kind of append this part to the big basically the base64 encoded data so please get this structure quickly out of the way i'll pause for a bit so you can type it out the reason why it's important to have all these these constructs in place is so that the data gets built up properly and gets displayed on the user's end as json data okay so let's go and open up the encoded packet now give it some space and then put our quotation marks now let's see what should be in our first line if we briefly take a look at the openc recommendation for metadata we need kind of a few things we need an image a name and a description the external link and the attributes are optional really but the the image and the description and the name are the most important parts now the image we already have because that we are going to generate as base64 data not a uri but we don't have the description and name so let's go and see how can we add it in here so the first part that you want to do is you want to put a curly brace then we're going to specify name like so and then another quotation mark so we wrap the name in quotation marks and we put the colon and then one double quotation mark with the ending string because at this point we need to put a comma to concatenate the rest you can see quickly how this is going to get out of hand but this is just something we have to do because it's on chain we have to build it up in this ugly way it looks ugly but at least it works okay so before i confuse you on what to do and how many quotation marks and square brackets and commas you have to have i've gone ahead and typed out everything as we needed to be for it to export correctly so go ahead pause this video and then actually see and type this out you need to have it exactly as i have and make sure it is if you do struggle you can find the repo on the ashlabs github repo to copy this part if you need to but it's good practice to type this out it will give you a good understanding of what's happening so what is happening here well like we said we want to construct something like this so if we go back to remix what we have here is exactly that we have a name field which i then have the value as replace we have a description field which i have the value as replace as well and then we have the image and remember that we append to this data svg that we've seen that i showed you on visual studio like there so we append this part simply and then we call and this is very important then we go ahead and call our build image function which is sitting up here the build image function remember returns to us a base uri well not a base uri but base64 string which we then can append with this that we place in the uri and that's why this comes after that now we are going to go ahead and replace the description and the name but just to show you how this works i'm going to save this file i'm going to go ahead and close this off i'm going to select the smart contract deploy it then mint one over there and once we have minted it i'm actually going to check the total supply and this time because the the token uri function is now going to return to me that the json data i can enter the id of my nft and click on token uri this will return to me the fully qualified uri that i can now use you can see it has the data application.json there so you can copy everything there and then once we go to a browser let's just use this one we paste it we can see that it returns to us the json data format now it's not formatted correctly in a nice way but you can see that we have got our name and it says replace it has a description and it says replace and then also we have the image which is this data string so if we take this data string now we copy it and we replace everything in our url and we hit enter we can see there's our image and that's exactly what we want and technically our on chain journey is kind of you know okay and right and we can now call it a day but you will have exactly the same image for all your nfts and that's something we don't want so this is now the part where we need to add some variety see how we can make it custom and have some fun with the program so it doesn't only export for us a green background with the text you know hello world on on top of it so let's go ahead and see how we can do that we now need a way where we can change the color using this full property of our svg and see how we can change it dynamically maybe by introducing a random value currently these values are assigned to hexadecimal value points which is determined by a color range well if we go to something simple by typing in css color picker and we get to our color picker over here we can see that there's the hex value of this particular color over there but in order for us to create some randomness maybe we should use a different color format and the one i want to use is this hsl it stands for hue saturation and lightness you can see that if i place the color over there and simply change the hue over there take note of this first set of numeric values so the first set only changes from 0 to 360. and that's kind of the randomness field that we can play around with the rest is basically the saturation so that changes from 0 to 100 and the lightness changes from 0 to 100 at the end here so this is the u the saturation and the lightness so if we choose a color we can simply randomize the u and we can get different colors for our background we most probably would choose a darker background and change the u and for the text i want to choose a very light color and then change the u as well let's now replace this hex value with our hsl value so we need to still keep the format so it needs to say full with those double quotation marks and then what we can say is hsl so technically it's going to look something like this it's going to have a value which is a solid value then let's give it an arbitrary value such as 50 and 25 like so basically this will work and produce a single color but we want to be able to randomize this value here in the front i am however going to duplicate this and just place it here on this full as well i am actually going to cut this out over there so i'm going to cut this out so that i have it closer to whatever we have working over here so we can see the different colors now like i said we want the actual text color to be a lot lighter and brighter so i'm going to make this a hundred percent for the um so let's think about it it's the u the saturation is going to be hundred and then for the lightness let's make it eighty percent so like i said these two values over here can range from zero to 360. so let's go and define some function that we can pass in here to make that happen for us let's go ahead and define a random function that we can basically reuse so i want to make some space and write function and then what are we going to call this function let's call this random num like so num stands for a number all right so random num and what we need to pass in is a un-256 we're going to create a modulus number because that's how we're going to get the random now if you don't know how modulus works i'm going to explain it in just a second and i also want to mention before we continue that solidity doesn't handle randomness very well because the ethereum blockchain was made to be predictable but for something as trivial as this we can simply work around a few key features that solidity gives us with the kcac 256 hash and modulus to get a unique kind of random number that we can then reuse in our color variables let's go ahead and add the rest of the parameters so we're going to add another u n to 256 and we're going to name this one seed the reason for that is we need some kind of seed beginning or some value that will adapt the randomness a little bit better and if you know what hashing is you also get something like a salt and now a salt isn't really necessary but i'm going to add it and it's most probably going to be our id or the integer value the id of our token just to add an extra layer of randomness then i'm going to make this public i'm going to have it as a view function and it's going to return to us by defining returns a uint 256 a simple integer value now how do we generate this value well let's assign it to a variable and let's call this variable num we're going to type caster directly into the respective type that we wanted this to be in then we're going to make use of the kickac 256 hashing algorithm this hashing algorithm will spit out a numeric value that we can then use modulus with so imagine this is what's going to happen at the very end we're going to say this is how this has to be the the modulus of the value that we place in there how modulus work it takes in a number so imagine this whole thing was 4 and the modulus was four this number will equal to zero because four goes into four once and then there's nothing remaining but if this was five then the remainder would be one but we can actually use this method of doing things to create randomness and random values because it's quite easy to determine what the length of something is and then kind of uh making a random value and we know it's going to always be underneath the modulus that we've defined over here keep in mind let's say this modulus was 10 it would generate a random number between 0 and 9. so if you wanted to be from 1 to 10 then you have to do modulus plus 1. i am however going to just leave it like this because we'll play around with the modulus value instead of adding it in here but just take that into consideration the next thing that we want to focus on is passing in a encoded string so i'm going to use the abi dot encoded packet and what do we want to encode well we're going to make use of the block block.timestamp and i think it's like that so we're going to make use of the block.timestamp and also check the message.sender the message.sender is the actual address that created this call we also want to add the seed phrase as well as the salt like so all right and this will create us now a nice random value based on the value that we specified in here and i'm going to show you how that works in just a second we still need to return this so we're simply going to return the number and once we do that we're done with the function we can now make use of this function so let's say we wanted to create a random value instead of this hundred between zero and three hundred and sixty what we can do is simply take out this hundred put in our single quotations because we are basically splitting up the string from this from that point and as well from this point okay so it's technically the same as doing that with it and then we put something in here but i'm going to keep it in one line so i'm going to put two quotation marks and then commas to specify what value i'm going to be putting in there and the value that i want to put in there is basically the random num and then we're going to pass 361. because this will create a random value between 0 and 360. so the function shows red and the reason is we need to still add these two arguments so we are later on going to add the block dot timestamps and more things but for now i'm just going to add a three and a three just be just to be random about it um we are going to replace these with the ids and also another assault that we can think of but for now let's just do this we also can't have this function as pure anymore it needs to now be a view in order for this to render then this is simply going to output a number so a numeric value which is fine so if we want to concatenate this we might also want to make this to string uh if we if we want to just to make it clear that we are casting this to string and we can do this because we've added the strings for un256 up here all right now basically we're going to do the exact same to this part over here so let's copy everything from this to there and let's replace it now this is going to be our format now we can basically go ahead and run this and we will get different color values for our images so different colors for the background and for the text so just to do a quick test we can remove this contract make sure we select it again then deploy once we open it hit mint so we at least have one that we can check and then in our token uri we put one wait for it to run sometimes the program might crash at this point and that's because it's working with a lot of data and it's running on the virtual machine but just refresh the remix and then just add the code again and run it so we're going to copy this go ahead over here replace this url then we're going to take the image data copy that and replace it again to get to the image and now you can see we've got a dark green with this light green color you'll see that the light green will always be a lighter color of this and that's why i say actually remix or not remix but the fact that solidity is very predictable means that if we enter the same values over here we're going to get the same thing especially if it's in the same transaction so that's why we have these extra two parameters to maybe add a salt like i don't know 12 and let's maybe add two so if we have 12 and two we save this we go ahead and close this contract do the whole process quickly again so deploy open it up mint then go and check our token uri on id number one we wait for it to compile then we can actually see how different it would be so now it is taking a while and like i said if this crashes at this point you might want to just refresh your browser i am actually keeping this part in the tutorial because this might happen to you and it usually happens when you run out of space on your on your browser when it comes to remix now don't be afraid i hope we didn't lose anything just go to your right workspace and click on the on chain and we can see that our change is still there let's wait for it to compile and then we simply can run it again so i'm going to click on on chain and then hit deploy i'm going to click on mint and then click on token uri passing it one so let's wait for it to compile there it is i'm going to select everything again i'm going to go to the your another browser type it in the url hit enter and then copy the data image now when we paste this we see that we get a different color on the foreground than the background for the text and that's exactly what we want we also don't want hello world the whole time so let's go and see how we can add that how we can work with mappings and how can we make this program more intuitive i think it's time to add some more hardcore logic and actually make the words appear differently and have different variants what we can do now is create a string array and then make it public and let's give it a name such as word values that sounds cool and the word values are going to be equal to an array like this this is simply an array of positive words like accomplish accepted absolutely admire achieve and active you can extend this as long as you want to but i'm going to use this simple list as an example at this point seeing that we on a positive trend if you watch the video till this point please go ahead and take some time to give me a thumbs up down below and leave a comment i really do read through the comments and maybe give me some suggestions what you want me to do next regarding on chain data i really read through the comments that you guys leave and take it into consideration the next variable we're going to add is not a variable per se but it's a structure it's called a struct now a struct is a data type that we can use to create our own data type with um how can i explain this so you start off by typing in the keyword struct and let's say we want to define how a word looks like the word is going to be our word nft so seeing that our nft is going to only consist of a background and a word i feel that this is a fitting name the word and we're going to say that this word struct is going to have a certain structure almost like a blueprint that we can reuse and recreate multiple of these instances what does our nft really need well it's going to need a few attributes such as a name and this is how you define the attributes we need a string name we're also going to need a string description so how do i know which attributes this needs well i i'm just basically basing this of how do i want to build up my nft okay so it's going to have a description it's going to have a name it's also going to have the bg u so the u saturation color for what we want to use and we also going to have maybe a text u and then lastly what i want is the value so let's make it value like that just so that we can simply save the value of the word that was chosen so that on a later stage we can reuse it now like i said this is simply a struct and not really something that we can reuse so in order to reuse this we can use a mapping for it so right below it we're going to create a mapping which is going to map from a you in 256 a number to the actual word so we are going to say that we have some kind of data structure right we're also going to make this public and we're going to say this is our words this is the name of it our words are going to basically say that id12345 is equal to one of these words we which we will have predefined all the values you'll see what i mean in just a second let's now take a look how we can implement this new word blueprint in our minting function we already check for the supply and if the supply is going to be less than our max supply which is 10 000 before we go ahead and mint it so just after this requires statement we can go ahead and create a new word we do that by supplying the word keyword and word is now a keyword because it a it's a struct then we're going to add the type of memory now memory is important because we need to tell solidity that this is a memory variable it's a temporary variable i'm going to give it a name and the name is going to be new word equals to a word type with the brackets and inside these brackets this is where you actually specify in the same order that we have them here which is name description u and text and then value keep in mind that this was test you this should be text you so let's go and specify the name so let's go and fill in the details for the first actual element that we need to supply to our word struct is a name then a description and so on let's go and try the name so we want the name to be something like ocn one because that's going to be our name of our nft in order to do that we can simply type in the keyword string to make sure that we are going to pass this as a string data type because it needs to match our first data type over there then we're going to make use of the abi dot in code packet the encode packet simply concatenates strings so we can have some quotation marks type in ocn with a hashtag put a comma because we want this value the next value to be dynamic and we're going to make use of this we're going to say that we actually want to concatenate the value for the supply plus 1. that should be our nft's id i am however going to cast this as a un-256 just to make sure that the data type stays the same and then i'm going to convert it back to string like so we are able to convert it to a string because we are using strings for uint all right and that is basically it what we do need is we need to close these things off properly so we need a three more brackets like so let's just quickly see so we have this one we don't need one there and we need one over there all right so let's just quickly see expected and got that okay so we've got a string which is the this one that is our bracket for string then we have our encoded encoded one which ends about there okay then we have our supply which ends there so we need one less okay and that's basically it so now we can go ahead and we can actually type in the next uh field so the next field is description now the description can simply be a text string we don't need to concatenate this so let's give it a nice description i'm going to say this is our cool uh cool nft actually let's make it unchain nft nice so this is our cool nft and you can see i simply pass in a string because it is string and i don't need to concatenate it with anything else it now needs a background u now we have already determined what our u is going to be by doing something like this now what i want to do is kind of take this out of this function and place it in our word where we concatenate it so that we can make use of it later on okay so i'm simply going to go ahead and now copy this random function all the way to the dot to string because this needs to be another string i'm going to make some space and put it in there now i'm going to not only just make use of three and three we actually going to put some you know better looking uh variables in there so let's try the block dot difficulty so the block dot difficulty could be a parameter that can be used as a seed and then for the actual salt i'm going to simply use the supply and then we also need the text view so this time i'm going to do the same but i'm not going to use the block.difficulty i'm going to use a maybe a timestamp okay so i'm going to use the block.difficulty for the top one and for the text the timestamp lastly we simply need the value which is also of type string but now we need the value of the word now how would we get a word from this list randomly if you look at our random function a random function takes a modulus which can be any length a array an array here has a length and we can specify that to grab a random nft or a random name for our nft so a random word value so let's go ahead and do that how you can do that is by specifying word values like so putting it in the block brackets so what this basically means if we type in one it's going to return to us the id on one so it starts from zero all indexes of an array starts at zero so one will be accepted if it was zero it would be accomplished and two would be absolutely all right but how do we get a random number in there well we can use the random num function that we have like so we can then supply the word values dot length because remember we get a length from an array and that means it will give us the length based on a random value based between zero and the length and because it's zero index we don't have to add one to it then we can again maybe give it a block dot um difficulty and lastly maybe we also add the supply for assault so now that we have the new word that's been created we have this in memory but we would like to save it on the blockchain so we have this mapping which is a uint to a word and it's called words how do we add it so just before it gets minted let's go ahead and add the words specify the square brackets add supply plus 1 because that's the id that we want this to point to and set that key equal to the new word that's all that's needed to finalize the minting function now every time that someone mints we will actually get this new word we can actually check it out because this is public so let's go ahead and do that i'm very excited so let's test this out if you go to this contract we can remove it and let's redeploy our contract i'm just going to say deploy click on our contract mint one and actually let's mint two or three there we go now because we the owner we don't have to pay for it and that's why i can mint it otherwise you need to actually pay so we can see that if we go to our token uri we can get our token uri back so this will work out the token uri but something that's also interesting is because we have this word mapping we can go and search for it now there's the words so if we look at id 1 we can see that there's all of our variables there's our name description the u which is now 24 171 and then the word is admire if we select the number two you can see that it changes and it's now the words absolutely seven and 141 so it means that our mapping is working and it's saving this data on chain we can now go ahead and complete this contract by hooking this up to the bolt image and the token uri function so the only thing that is missing is to actually use those values so let's go and add in our build image param let's say this needs to take in a token id like so we're going to use this token id to actually get the word off of our mapping how do we do that well we can specify again that we want a word type and it's going to be of type memory this is going to be our current word that we work with and we're going to equal it to the words which is our mapping in the brackets passing the id now we will get a copy of that word in our current word which is perfectly fine we're going to go ahead and replace this all now because we don't need that to say current word dot bgu the same we're going to do for the text so everything from there to there it's going to be the current word dot text you and then we also want the value to show up so over here we now need to put our single quotations and our double double commas then we're going to say the current word dot value like so and this should be enough to actually use this word when we build our new image the last thing that we have to do is actually pass in our token id over there so we're going to do that and we also want to use our name and description in here so the only thing left to do is to basically again pull in our word so i'm going to just simply copy this line over there and on this function right after the require statement because we want to make sure that this token exists before we go and grab it from our list we can go ahead and do that next we have to pass in a token id and i don't like the fact that it's just like this so i'm going to change this to have an underscore remember to change this over here as well then now and as well over there i'm just going to do a search for all the tokens that's not using an underscore with token id and it seems that that is fine it's just sticking to my coding convention so now that i have this word memory current word i can go ahead and replace a few things so all i need to do now is i can go ahead and go in here and then say i want to use the current word dot name and where it says replace over there i'm going to use the current word dot description and that is it we are done so now comes the actual fun part where for the last time we can deploy this contract and see how it works now let's just test for the last time on the javascript virtual machine just to quickly see if everything works so i'm going to mint one i'm going to check the total supply and i am indeed going to verify that our token uri works this time it's very important to do this before you really go and do it on the live network i'm going to put it on the url and there i can see there's my new data i'm going to copy that paste that in and see we've got our word it's active perfect next i'm going to do the real thing but on the test network so make sure that you are on the test network of course go to your taste network i'm going to use rinkeby if you want to deploy on the test network make sure your meta mask is pointing to the test network and if you select injected web 3 you should see rinkeby network 4. i'm going to go ahead make sure that i have my smart contract selected and then hit deploy while this is working metamask will pop up and i'm going to confirm the transaction it's going to take a few seconds until it's deployed keep in mind while we at this point to always keep your data to a minimum and experiment to what extent you can push it by using different svgs in the future videos we will get more to complex structures and and also maybe do a full-on layer solution with svgs but stick around for that video for now i see that it's successful i can see there is my nft contract i'm gonna go ahead and mint maybe three nfts so let's go ahead and mint one and i also wanna just for now go to open c to the test network and go to my profile hopefully if everything is successful our collection should start showing up here so let's just go back to remix i see that one was successful i'm going to mint another one so let me mint another one click on confirm and then i can so long click on total supply and see that i have one at least let's wait for the second one to complete and let's also click on another mint as well so let me do another one so total supply is now two and there's another minting in process so we should have three while this is running i'm gonna go back to openc like i said and refresh let's see if those nfts are in my wallet if you have refreshed your wallet and you don't see your nftc8 don't worry it takes about a minute or so i'm just going to jump back to remix and copy my contract's address by clicking on this button then head over to the rinkeby dot ether scan this is the test ether scan and it works exactly the same as the real mainnet one but in this case i want to see my my contract so over here i can see there was a contract creation and then i minted three nfts which means this unchained nft that i've created is healthy i can click on it and i can see there's my max supply so far and i have one holder we can go back to openc and refresh i'm sure by this time it should be there and there we go and there is our three nfts how cool is that i think this is pretty brilliant and we have accepted admire and active now we can go ahead and mint another one and let's see how long that one will take to pop up but while that is in progress i'm going to click on one of the nfts and you can see that it's super clean it's an svg it's on chain it has a name it also has a description which is this is our cool on chain nft and then obviously when you want to add attributes that is a lesson for another day but you can as well in the metadata if i click on the collection itself i have now the right to go and edit it up here to put in a nice banner and a icon over there and the metadata will start populating and filling in items owners floor price and volume if people start trading with it this is not a collection that's on the live maynate but you can just simply point it to the main net and deploy the contract now i am super excited to have gone through this journey with you guys i hope you enjoyed this video it's as simple as that to create on-chain nfts with svg's that sounds quite cool anyway guys i hope you enjoyed it like i said give this video a thumbs up and as always i would appreciate it if you guys subscribe for more content if you get stuck click on this discord or any of the other channels our discord channel is thriving and there's a lot of community members that will help you out till the next video guys cheers for now
Info
Channel: HashLips NFT
Views: 15,423
Rating: undefined out of 5
Keywords: polygon, ethereum, nft, opensea, nft collection, hashlips, blockchain, generative art, generative nft, programming, code nft, ipfs, solidity, how to market your nfts, nft marketing, promote your nfts, nft marketing strategy
Id: UBGXFV1TQxc
Channel Id: undefined
Length: 91min 6sec (5466 seconds)
Published: Wed Oct 06 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.