How to implement an ERC721 Token and connect it to OpenSea (DAY 2) - YouTube

Channel: Kie Codes

[0]
Welcome back to day two of my journey to  develop my first-ever crypto collectible  
[5]
and smart contract for the Ethereum blockchain.  If you haven't watched the first video I highly  
[11]
recommend it. Today we will write our first  smart contract in solidity and figure out  
[16]
how we can connect our own NFT  to marketplaces like OpenSea.  
[21]
If this sounds like a lot of work  you're right it was a hell of a day.
[33]
So here is the idea: I want to develop  a non-fungible token called Date Token,  
[37]
so you can mint your own token for every date  in our calendar. From year one till now. Unless  
[43]
somebody else already owns that token. Every Date  Token is unique. You could mint your birthday,  
[49]
or the date of the moon landing or the  invention of the light bulb, whatever  
[53]
date you want to own. And I want to store all the  needed information inside of the blockchain: year,  
[60]
month, and date. That sounds like a small and  achievable goal for one day let's see how it goes.
[67]
Some of you might ask: What is an NFT?  NFT stands for non-fungible token. A  
[72]
token is something you can have inside  of your wallet. If you have one ether,  
[76]
that would be one token of ether inside of your  wallet. But what does non-fungible mean? Fungible  
[81]
means replaceable by another identical item  and non-fungible means basically the opposite.  
[86]
So if I give you a dollar and you give me one  of your dollars we both end up again with one  
[90]
dollar. There is no value difference in your  dollar to my dollar. Dollars are fungible.
[95]
But if we were to trade Pokemon cards. I give  you one of my Pokemon cards and you give me  
[100]
another one of yours. We both have the same  amount of pokemon cards after the exchange,  
[104]
but the value of the two cards is not necessarily  the same. Pokemon cards are non-fungible.
[109]
The same goes for the Date Token. If  I owned the date of the moon landing  
[113]
and you own some other random date, I  certainly don't want to trade with you,  
[116]
because the intrinsic value of my  date might be higher than yours.
[119]
I learned that there are different tokens on the  Ethereum network and each token needs a certain  
[125]
smart contract to be implemented in order to work.  If you want to create your own currency you would  
[132]
need to implement the ERC20 token and for NFTs  you use ERC721. ERC20 and ERC2721 are basically  
[142]
interfaces you need to implement in your smart  contract in order to be recognized as a currency  
[147]
or an NFT on the Ethereum network and so that  other dApps can identify and use your tokens.
[154]
If you have looked into NFTs before, you  certainly found the website OpenSea. OpenSea is  
[159]
a marketplace. On there you can buy and sell your  NFTs. All of these are so-called ERC721 tokens.
[165]
You can also create your own NFTs here on OpenSea.  You just need to upload whatever graphic, video,  
[170]
or audio file you want and OpenSea creates an  OpenSea NFT for it. What OpenSea basically does,  
[175]
is creating an OpenSea token, which is connected  to your media file using their own smart contract.
[180]
But doing that would be way too easy. We want  to create our own smart contract. In order to  
[185]
create our own ERC721 smart contract, we could  write implementations for all of these functions.  
[190]
Or we could use OpenZeppelin: A library  for implementing different types of ERC  
[195]
tokens. OpenZeppelin can be installed using  NPM and helps us by implementing almost  
[200]
all of the functionality we need for our  ERC721 token. We just need to fill in the gaps.
[206]
So I installed OpenZeppelin using NPM and built my  
[209]
first ERC721 smart contract.  This is what we got so far.
[214]
I created a file "date.sol". I added  a little header. I imported the  
[219]
OpenZeppelin ERC721 contract and the contract  date is ERC721. I call the constructor,  
[227]
define my own token name, and my own token  symbol. I inherit all the functionality I need.
[232]
And, yeah, let's try to  compile it. "truffle compile".
[237]
So the next step is to actually migrate  our smart contract to our local ganache  
[242]
blockchain. As far as I know, I  need to write "truffle migrate".
[247]
Okay, it went through. In ganache, there's a tab  called "contracts". Going there I see a Migrations  
[254]
and I see a Date contract, but it is not deployed,  
[258]
which means we have to add our Date  contract to our migration script.
[262]
For that to work, we need a new file in  our migrations subfolder starting with a  
[267]
2, so it's the second migration step. I call that  
[271]
"2_token_migration.js". In there i need to load  my smart contract and deploy it to the blockchain.
[279]
So what's basically happening here is,  that we import our "date.sol" file somehow  
[285]
and we export a function that calls the  deployer to deploy our data. Let's try it out…
[291]
And this time you see, that a  second migration phase is executed:  
[295]
"2_token_migration.js", "Deploying Date"
[298]
So if I open up ganache now  I see that our contract Date  
[302]
is actually deployed and has the  following address. That worked …
[306]
After this first success, All I need to do is to  implement the rest. I want to store the year month  
[311]
and day on the blockchain, I also want that  the user can add a title to each date, and  
[316]
I have this idea of different materials to make  minting more exciting, but more on that later.
[321]
The development cycle for smart  contracts basically works like this:  
[324]
You implement a function. To make sure it  works, you implement a Unit Test for it.  
[328]
truffle.js comes with a testing framework  so you can make sure your smart contract  
[333]
works before you deploy it locally to  a test net or finally to the main net.
[337]
It has been a couple of hours now and I  think I have the Date token smart contract  
[342]
ready. So here's what I got so far …
[344]
I want to store the year, the month, the day, a  title for the date token, and the color on the  
[349]
blockchain. So what I did is to define this struct  metadata. I added this mapping here, where I map  
[356]
the token-id to the metadata. This is basically  how you store data inside of the blockchain.
[361]
The constructor is executed when you deploy  your smart contract to the blockchain  
[366]
and because I want to have  some Date tokens for myself,  
[369]
I call this mint function nine times to generate  some interesting Date tokens for my wallet.
[374]
The mint function takes a year, month, day,  and a color, as well as a title to create a  
[380]
new token. It's defined "internal" so only the  contract itself can call it and nobody else can.
[387]
In order to create a token for  yourself through the web app,  
[391]
I have a different endpoint  defined which is "claim".
[394]
It has the same parameters, not the color because  the color is randomly chosen, it's external so  
[401]
everybody else can call it, and it's  payable so you have to pay a little fee  
[404]
in order to create your own Date token.
[406]
It costs 10 Finneys to create a Date token. So if  that is not given you get a little error message.  
[413]
And then we check the incoming parameters  for validity. If they are valid, I generate a  
[418]
different color based on some probabilities I have  chosen. Put it into the mint function and transfer  
[426]
the 10 Finneys that you have to pay to my account  because I am the owner of the smart contract.
[431]
I can "get" a Date token: So I  want to read the metadata that  
[435]
is associated to a token-id. So  that's the "get" function here.
[439]
I can get the title of the Date token.  Either by token-id or by year, month, day.
[445]
I can change the title of the Date token. But  only, If the token exists and, down here, if  
[452]
the owner of the Date token is calling this  endpoint. If you don't own a Date token,  
[456]
you can't change the title.  If you own it, you can.
[459]
One cool thing is that truffle.js comes bundled  with a testing framework. The first thing we  
[465]
test is if, after deployment of the date token,  the owner of the Date contract is correct. In  
[470]
the test environment, the first account in the  ganache blockchain is deploying the contract.  
[476]
So we check if the deployed contract  date has the correct owner. Like this.
[482]
We check if the name is correct, if the token  symbol is correct, we check for the base URI  
[487]
or the token URI. Then we check if I as  the owner get all the Date tokens that  
[493]
I have defined in the constructor.  And then I check that minting a date  
[496]
actually works and that you have to pay  the 10 Finneys to get the date token.
[500]
I know that I went over this code  rather quickly, but remember the  
[504]
link to all the code is down in the description  below if you want to have a closer look.
[507]
Now, let's try to run the  tests, compile the contract, and  
[512]
migrate it to the ganache blockchain.
[515]
"truffle test" runs the test suite. All the tests  
[518]
went through successfully. Let's  compile the contract: "truffle compile"
[524]
"truffle migrate" to migrate the contract  to the blockchain, but since we already have  
[529]
migrated the contract to the blockchain  once, we need to add "--reset" to the  
[534]
command line parameters so we reset the  blockchain and can redeploy our contract.
[541]
Bringing up ganache now, I see  that the contract is deployed  
[544]
and that I paid a little bit  of gas for the deployment.
[547]
Looking at MetaMask, we see that MetaMask is not  showing the nine Date tokens, that we should have  
[554]
because of the deployment of our smart  contract. But we can add the token…
[559]
Go to "custom token" and  paste the contract address  
[562]
here. It automatically reads the token  symbol. We go "next" and see nine Date tokens.  
[568]
So now in our MetaMask wallet, we see the  nine Date tokens, that we own. Amazing!
[574]
If you remember OpenSea and all the little  images on it, you might ask yourself:  
[579]
"how does OpenSea know what  to show for each token?"
[582]
Looking at the OpenSea developer documentation,  
[584]
you see that each ERC721 token has something  called a "tokenUri". In there you can store  
[590]
any kind of URI and OpenSea reads this to  get its needed information. It basically  
[595]
expects a JSON like the following. In here the  title and description of the token is defined,  
[600]
as well as a link to an image, and some  optional arbitrary attributes. So what we  
[605]
need to do is to implement a service which  returns the JSON for each of our tokens.
[610]
After I found out about this, I  spent the last couple of hours  
[614]
thinking about a nice representation for  our Date tokens so they look good inside  
[619]
our collection on OpenSea.  Here is what I came up with…
[622]
The Date token should be represented by this  futuristic-looking card. On there we have the date  
[629]
written out, as well as the token-id and a barcode  encoding all the information of this token. The  
[635]
top half consists of three parts. We have five  squares in the center which encode the day of  
[640]
the month. So it looks different for Elon Musk's  birthday or the moon landing or the start of the  
[646]
Ethereum blockchain. It is a 5-bit encoding  of the numbers 1-31. The triangles represent  
[654]
the month. So January looks different than June or  December. 4 bits for 12 months. And the last part,  
[661]
the dots on the circle, represent the year.  Which again is simply a binary encoding.
[668]
OpenSea supports animated SVGs. So, of course, I  want it to be animated. And because I want to have  
[676]
some rarity factor for each minted date token, I  also invented eight different colors: blue, green,  
[684]
red, black, silver, gold, neon, and pearl which  get chosen randomly during the minting process.
[692]
Now, let's program a  javascript express.js service,  
[697]
which generates those SVGs and  the JSON needed for OpenSea.
[703]
So how did I do it: I implemented an express.js  server app. I used web3.js to connect to our  
[711]
ganache blockchain like this. After that, I got  all the contact information from our compiled  
[717]
JavaScript ABIs that truffle generates  in order to interact with the contract  
[723]
and handing in the contract address from our  migrated contract. This way I can actually call  
[729]
the functions inside of our smart contract. Then  I have one endpoint for OpenSea to get the JSON,  
[736]
and another endpoint for  OpenSea to get the SVG image.
[740]
Inside of the first endpoint, I call  a contract method "get". You remember  
[746]
"get" is the contract method that returns the  metadata that we store inside of the blockchain:  
[751]
year, month, day, color, and title. And  I use this information to generate the  
[755]
JSON for OpenSea and to put in the URL to our  SVG endpoint to get the right representation.
[762]
And down here we generate the SVG. All of the  code generating the SVG is inside the "svg.js"  
[770]
file that I put into the repository  as well. So if you want to look at it,  
[774]
there's a link in the description below.
[777]
And that's it for today good night.
[780]
Day two is a wrap. And what a day it was!
[784]
If you want to follow my journey  consider subscribing. Thanks to  
[789]
my patrons for helping running  this channel. I see you in one  
[792]
of my other videos if you want. And  as always have a lot of fun coders!