DAPPCON 2024: On-Chain Metadata And Asset Generation For Ethereum NFTs - Moritz Fuller

DappCon 2024 · May 2024 · 59:33

Explores on-Chain Metadata And Asset Generation For Ethereum NFTs.

Speakers

Topics

From DappCon 2024, hosted by Dappcon Berlin.

Transcript

my name is Mor I'm a developer relations engineer at definity and today I'm going to give a workshop on generating on metadata and assets for ethereum nfts and before we start with that I have to go over some theoretical stuff first so we make sure that we actually understand everything that we are going to build so I'm going to give you a quick intro to the internet computer then we are going to talk about canister smart contracts their unique capabilities and how we can use those capabilities to interact with ethereum smart contracts okay um throughout the slides there are going to be a couple of QR codes that you can scan for further

reading material but you don't have to keep your phone out all the time you could actually just scan this QR code once that will lead you to the slides I think the display should be my slides right okay perfect um you can just scan this QR code once to get to the to the slides and then within the slides you can just click on the QR code and it will get you to the respective further reading material so by now a couple of you probably already have their first question and that is what is the internet computer right this is ethereum conference what is the internet computer so in one sentence the internet computer is a decentralized and permissionless Cloud build on blockchain technology and before we start with the presentation I

quickly want to get a feeling of the room so how many of you have heard of the internet computer before okay awesome and how many of you have built on the internet computer before okay and how many of you are planning on building on the internet computer okay yeah maybe we can increase those numbers at the end of this Workshop let's see all right so a permissionless cloud built on blockchain technology let's add a bit more context to that so after Bitcoin and there should be my slides at least I'm seeing one on my screen see here

SL okay weird glitch okay sorry um okay Bitcoin and ethereum is the internet computer uh the inter computer say third generation blockchain and it solves problems that ethereum has not solved with its evolutionary step and that means that the internet computer is a high performant horizontally scalable blockchain that is able to run very general smart contracts and even host web pages and I want to underline the statement a little bit by quickly comparing some of the key metrics between the internet computer and ethereum let's start with the transactions per second here I see is two ERS of magnitude more performant same for transaction finality transaction costs even more and for the

storage costs again even more with it only costing $5 to store a gigabyte of data for a year and while the internet computer excels in those metrics of course ethereum is constantly improving through Solutions like sharding and layer twos and another thing that is not on this table is that the etherium community is of course and the ecosystems of course way bigger than that of the internet computer and that ethereum is a proven and trusted technology that has been around and used for many many years now and for the use case of today's Workshop we are going to combine the high performance capabilities of the internet computer with the security and decentralization that ethereum is known

for so with that out of the way let's next talk about canister smart contract so canisters combine code and state in one place and when you want to deploy a cadaster you first have to compile that canister from a highlevel program language like Russ for example into a wasm module and web assembly or wasm is a low-level and portable binary instruction format and in theory all languages that compile to wasm or that have an interpreter that can be compiled to wasm can be used to write catas smart contracts and that includes rust which is what we are going to use today or go C C++ Moko JavaScript python so many languages to choose

from okay so canisters are an evolution of smart contracts as you probably know them or think about them and for us today it's easier to think about them as decentralized server so let's go over some of the unique features that canisters can offer them make them more similar to service than traditional smart contracts the first one here are timers so canisters can automatically execute smart contract logic either after a specifi specifi delay or periodically so you don't need any offchain infrastructure to do that then we also have the reverse gas model which allows your users not to know anything about crypto wallets or tokens and that works by pre-charging the canister with gas and then the canister itself pays

for the invoke computation canister can also call into web2 services like for example an exchange rate API or an RPC nodee provider or RPC provider for refer that we are this is something that we are going to do later today and yeah this video is going is called HTTP out calls and because canisters operate at web speed users don't have to wait long for transactions to be finalized and that offers them almost the same experience that they are used to from interacting with traditional web2 Services the internet computer also provides a secure and verifiable way to Generate random numbers directly within smart contracts or canisters and also thanks to chain key signatures canisters

have control over a unique ecd is a key pair and they are able to request signatures with the corresponding private P key to be computed and this enables canisters to natively hold for example ethereum or Bitcoin or any other chain that supports ecdsa signatures or tokens from chainset support ecca signatures and we are planning on um adding support for other signature schemes as well with currently we're working on schnor threshold schnor signatures and the plan is to release them by the end of the year um we talked about storage previously and but it didn't tell you how much you can store in a canesa So currently you can store 400 gabes of data with plans to enable terabytes in

the future and last but not least canister can serve websites and answer API requests over HTTP and this makes it extremely easy for developers and applications to integrate with your canisters and it also allows you to deploy your entire depths infrastructure on chain so also the front end so now that we know about the unique features let's talk about how canisters can leverage those to interact with ethereum and with the HTTP outcool feature that I mentioned earlier canesas can actually rate from ethereum and they do that by making an HTTP out call to an RPC provider with their request for example they want to get the logs for an event and the result is then becoming

available in the context of the smart contract after the response is getting back but they cannot only read the theum state they can also write it and that works by leveraging the chain key signatures that I mentioned earlier so in this case we're using a threshhold ecdsa signature scheme the canister creates a transaction for example using eers RS or alloy in Rust and it then asks the threshold ecsa scheme to create a signature on the transaction and the sign transaction is then being sent to an RPC provider again using the HTTP out calls feature and through this canister on thec can trustless interact with etherium okay and because building a

canister that securely and correctly interacts with etherium can be quite challenging we actually provide the so-called evm RPC canister for that and this canister acts as a gateway to ethereum and other evm chains it's basically a helper canister that does a lot of the heavy lifting for us and it allows the developer to focus on the actual use case without having to replicate all the necessary logic to interact with ethereum and some of the things that canister does is that it for example calls multiple RPC providers instead of only one and it then checks that the responses coming back from the RPC providers are actually consistent and this removes the risk of centralization if you only call call a single RPC

provider and it also provides convenience methods that we can use without having to assemble the Json payload first and it also Al um provides the responses coming back from the RPC provider encoded and candid which is our interface description language um and that means that the response is immediately useful in the context of a canister without first having to De deserialize it into something that we can use in the canister so now that we have the theoretical knowledge we need let's talk about what we want to build and the project we are building today boils down to building a co-processor for ethereum so as you know ethereum smart contracts are pretty constrained Computing environments and co-processors enable to

extend the capabilities of eum by offloading specific tasks to a more powerful environment and in that case that more powerful environment is the internet computer a co-processor could for example calculate some complex numerable function or run some crypto like AES or RSA or in our use case today generate and store nft assets and metadata let's go over a example flow so it starts by the ethereum smart contract signaling that it wants some co-processing to be done by emitting an event with the details about the job the ICP co-processor cister then regular fetches locks from the contract using

the evm RPC provider uh the evm RPC canister and timers and upon seeing a new job event the canister runs the requested job and during the processing the canes can do many things it could for example store data or make transactions to other chains call other canisters and so on and so on so basically a lot of freedom here and if needed the result can be written back to the ethereum smart contract as well and here again we are going to create a contract call in the canister sign it with threshold ecdsa and then send it to the network through the evm RPC canister and in this callback function we assert that the caller is actually

the co-processing canister to make sure that no one else is able to submit results that shouldn't be there and because this co-processor architecture is very versatile and can be leveraged for a lot of different use cases we actually provide a stter template for that the so-called chain Fusion starter and here of course the co-processor logic is already implemented and the developer only needs to worry about what computation they want to carry out in a job and this sta template under the hood also uses the evm RPC canister to interact with ethereum and it comes with a Dev container which is basically a Docker image with all the dependencies pre-installed for minimal friction to start building right away and this starter template is also what we are

going to use as a starting point for today's Workshop so finally what are we going to do we are going to generate and store the metadata and the assets for an IRC 721 contract fully on chain using the internet computer saay coprocessor why are we doing this because generating assets and metadata off chain beers the risk of rig mints and centralization generating them onchain is not really practical due to the extremely high cost associated with it and storing them on ipfs doesn't really allow for dynamic nfts in a decentralized way so what we want to do is we want to enable fair and fully decentralized autonomous mints and we also want to enable fully onchain

dynamic nfts and how are we doing that we are going to start from the chain fion starter template to then on top of that build a co-processing Cana that listens for mint events from an earc 721 contract and upon seeing such a mint event that triggers the metadata and asset generation using the onchain randomness provided by the IC and this is the last slide this is a sequence diagram to visualize the entire flow I think this is very small actually um but on the left hand side there is an ERC 721 contract deployed on eperium on the right hand side we see the evm RPC canister and the chain Fusion sted canister deployed on the internet

computer and the sequence begins with the user minting in nft on the ERC 721 contract which emits a transfer or mint event and as you already know by now the chain Fusion or co-process in in general regularly fetches locks from the IRC 721 contract y the evm RPC canister and use using timers and then the chain Fusion starter executes a so-called job for each mint event it sees and in this case the job is that we generate and store the assets and the metadata for the nft using onchain Randomness provided by the internet computer and because canisters can serve um web the assets so both the metadata and the actual image are

available via HTTP after the generation immediately and if we want to get to the URL that serves the metadata we simply follow the URL returned by the token URI method on the ESC 721 contract okay that's there should be QR codes here okay now they're here um yeah so if you want to code along uh scan the first QR code which is the uh link to the St Repository that we are going to use and because time is limited um I don't know if you are able

to code along with me maybe it's a bit too quick um so on the bottom uh the bottom QR code is the outcome of today's uh Workshop so if you are behind or something you can just uh copy paste code over and maybe that way try and catch up okay so let's head over to the repository and the first thing we are going to do is that we are going to create a new repository off of that template and I'm just going to call this workshop and as soon as that one has

been created we are going to start one of those Dev containers or how GitHub calls them code spaces we're actually going to click on those three dots here and then we say new with options because because we want a more beefy spec than the spec that it usually runs with and I'm going to go for the 8 core 32 GB of RAM here and I would uh suggest you to do the same and while we are waiting for this to run so this opens vs code in your browser but for some reason it doesn't really work for me so I'm just going to connect with my local vs code installation you can do whatever you want uh either use the one in the browser or your local installation W it um container spins up we are quickly going to go through the existing infrastructure so first there's this

co-processor smart contract that we basically went through um in Fury and as you can see it has a a function here called new job that is payable so if you pay 0 Z EA to it it emits this new job event and it transfers to 0 Z eer to the co-processor contract uh canister so that that one can uh first first of all pay for the computation and also pay for writing the result back to the smart contract and to write back we are going to use this call back function down here and that checks that the send of the message is the co-processor to avoid anyone else writing results uh writing results and then we go into this chain Fusion backend here and in here we have

our job module and that contains the logic that is being run on each new job event that we are seeing and this one is pretty simple we basically just calculate the 20 Fibonacci number in this line and then we are going to write that result back to the ethereum contract and that's that's it and what we are going to do in this Workshop is that we are going to replace the co-processor contract with an IRC 721 contract and we are going to replace the job logic here with a logic that generates the metadata and the assets on chain using the randomness provided by the IC and what we are not going to do is we're

not going to write any anything back to to ethereum so just uh this C processing as kind of like a side effect okay so by now I think this should have spun up so I'm going to click on the three dots again and then click on this open Visual Studio code which will connect my local vs code installation to the STA container and the first thing we are going to do here is that we we are going to replace the co-processor smart contract with an ethereum smart contract and to get this etherium smart contract you can go to book. getet found. sh and then you go into chapter or section 24 and Foundry is basically the smart

contract development tool chain we are using for our e contracts in this Workshop so once you are there you scroll down a little bit it's not the first implementation it's actually the one here down at the bottom that says extending our nft contract functionality and testing we're simply going to copy this and paste it back into the co-processor and we also going to rename that to nf. and now there's um a bug because the um base contract the ownable base contract actually um expects a Constructor argument so let's add that real quick down here so rewrite in line

25 ownable and then this contract should initially be owned by the sender of the message so basically the deployer and the next thing we are going to do is that we are going to modify the script that we are using to deploy this coprocessor locally and now we're going to of course deploy our nft smart contract so we're going to modify the import up here we can get rid of this argument that we are not needing anymore we're going to rename this to nft this one to nft as well and here we creating a new nft contract and now we have to also change our Constructor arguments and the smart contract expects a name a

symbol and a base URI so the name is going to be depcon the symbol is going to be DC and the base URI um this is actually a method that you can call on the smart contct called token URI and what it does is it concatenates the base URI with the token to kind of form like a a URL and that URL usually points to a Json file and the Json file is basically the metadata for the nft and as I said caners can serve web so in our case we are going to use a canister URL as a base URI and that canister URL follows a certain schema so it always starts with the canister ID which is basically the

contract address followed by a domain name and the domain name because we run this locally is Local Host and then we also have to specify the port that our local internet computer node runs on so you can find the contract address or the canister ID if you go to DFX Json in the root folder and then here it's the first canister basically defined chain Fusion back end and this is the ID so we're going to use HTTP canister id. localhost and then callon 494 free 49 4 fre and then a slash and that's basically it now we

also want to Mint a couple of nfts when we deploy this so we are going to rename this to nft and then mint 2 which is uh an argument that is exposed on the smart contract that expects an address to Mint talking to I'm just going to copy a random address from EA scan to do that so let's M it to this address and the value that we have to send along is 0.0 E8 eer because this is the Min price that the contract specifies okay now we have the ethereum smart contract implemented let's continue with the

co-processor so for this we go into Source chain Fusion backend again source and then into the job module and in here we're going to get rid of the logic that currently exists and we are also going to rename this new job event to Mint event and now we can get rid of this debug because we don't really need it and yeah the mint event is actually a transfer event but we only listen for transfers from the zero address thus we're going to just call them mint events and you can see the event structure if you go to the definition or the specification of erc721 and you search for transfer you will find this

entry here so it has a um basically three attributes a from address a two address and then also the token ID and in our use case we only care about the token ID so let's rename this to token ID and now we have to modify this from method or function down here as well because initially all the events that received by the canister are basically just by the evm RPC canister basically just generic locks and we now have to convert the generic lock entry to a mint event and to do so we need a token ID and to get access to this token ID we look at the topic topics field that each

lock entry has so this is a vector of strings that you can yeah see in the struct and the first item of this topics fields of that of the vector is always the event signature and that is a catch 256 hash of the event name and the input argument types and the rest of the items are indexed arguments of the event in order of their appearance so all of the arguments here are indexed so the um yeah item at index one would be from index two would be to and index 3 would be token ID and that's why we are going to to take the third or the item at index number three and then of course we also

have to rename this one to token ID and this one to token ID as well okay this one is actually also a a mint event okay so the next thing is that we are going to get random bytes from the internet computer and for that we are defining a variable called random bytes and that calls or that is um being filled by this method called random bytes that is asynchronous so we await it and that's basically it now we have to implement random

bytes and random bytes gets get random bytes from the the system basically and it returns a 32 uh bite array so an async function called get random bytes takes no arguments and returns a 32 byte array and in here this is a tupple what's being returned so we uh destructure it and we make a call to Raw rant which is an asynchronous method so we await it and it could fail so we expect should not fail and now we have to import this raw Rand and we import imported from the IC

cdk which is basically a canister development kit and this is the path I think vs code takes that away from you if you're using uh vs code which we probably all do now um okay and now we have to convert those this this this uh bite Vector into a bite array so we call uh raw Rand and then try my into and then because this could fail again we expect should not fail this is of course not how you should do it but uh yeah for the sake of time all right um so next we are going to seat a

random number generator using those random bytes and for this we are going to use Chara 20 from seat and the seat are the random bites that we just obtained from the system okay so now we have a random number generator seated by the randomness provided by the system and next we are actually going to generate the first or the attributes for our nfts so let attributes new variable and we're going to call a function called generate attributes and that takes a reference mutable reference to the random number generator so let's Implement that method first we are going

to add a new struct the attributes struct and that has two Fields a uh public background color which is a string and also a public Circle color so you maybe already have a little bit of an idea what this nft is going to look like which is also a string okay now um generate attributes oops this takes a mutable reference to a random number generator which is charer 20 and it Returns the

attributes attributes struct so we are just going to create this attributes literal in here and we're going to say the background color is going to be the value of a function called to select value that takes a random number generator and the same for the circle Coler which is again a call to select value where we pass the random number generator and now of course we have to implement select value so let's Implement that one and this one takes again a mutable reference to the

uh random number generator and it returns a string actually so first we're going to because our nft is actually going to be in SVG I didn't mention it yet first we're going to define a couple of uh SVG color keywords so we have um an array here which contains a couple of keywords color keywords so we maybe have blue red and yellow and green and then we associate weights with

those color keywords so the higher the weight the higher the probability that this specific color keyword is going to Define either the background or the circle color for the respective nft and they are all going to have a weight of three except for green which is going to have a weight of one so green is rarer than blue red and yellow and now we are going to create a weighted index distribution oh sorry yeah of course possible is that good or more yeah okay sorry I hope you could follow along still kind of okay um weed index um let's

import this and we are going to create a new one based of the weights that we specified and we're going to unwrap this and now we're going to actually select our color keyword by um picking a random value from the arror using the weighted index distribution and the random number generator and because this is not a string yet we have to convert it to a string and now what's missing is that this sample here expects um that you import this distribution from the Rand crate so we are doing that as well okay

now we have the attributes for our our nft so we have a background color and a circle color and the next step is that we want to generate and store the metadata for the nft this doesn't return anything it just has a side effect generate and store metadata and this takes a pointer to the mint event or a reference to the mint event and also a reference to the attributes so let's implement this down here as well generate and install metadata it takes um a reference to a mint event and a

reference to the attributes and it returns nothing so in here we are going to create the Json metadata using a library called 30 Json and then we are going to serialize that Json into a bite Vector variable that we call Body and to write Json literals in our rust code we are going to use the Json macro so let's define the metadata data variable here let's use the Json macro and let let's yeah write the the metadata basically so the first one is the name the name is going to be a

formatted string that consists of um depcon number and in here in the parentheses we're going to insert the um mint event and then the token ID um this is a typo [Music] Ates and this I have to import as well um then we are going to also point to the actual image which is the actual SVG that we are going to generate in the next step and here again we use the canister URLs right um so we are starting with http

then this is going to be our canister ID then Local Host and then 4943 which is the port that the local internet computer node runs on and then this is the token ID and the file type or the file ending is SVG and now we have to fill in the curly braces here and we are doing that by filling the first one in with the actual canister ID and I don't have to copy paste it because uh the iccd K provides a method for me to get the ID of the contract that I'm executing this function in and because this is not a text I have to convert it into a text and the other thing is again the token ID associated with the

mint all right and now we're going to generate the attributes so if you would trade or sell this token on openc you would have a nice um yeah representation of the attributes associated with the nft which is the background color and the circle color and this is an array of objects that contain two keys or Fields the trade type which for the first attribute is the background color and then of course also the value associated with the trade type which we are going to get from our attributes and of course this is going to be the background color and now I have to clone this as well and now for the second one I'm just going to

to copy paste this and I'm going to rename the background color of course to Circle color and then down here again I'm going to use Circle color so this is it this is the the metad data for our NF that points to the actual image that is stored on the canister as well served via HTTP all right so I said we generate metadata but we also need to serialize it into a bite vector and that's what we are going to do now so we're going to create a new variable called body and here we're going to use the two method that is exposed by 30d Json we are going to pass a reference to the metadata in

this and then we are going to because this can fail expect that this should work of course again not best practice all right so to store our asset to now later on Surface it to the web we use a method that is already provided with the starter template and to be able to import this method into our job module we have to first go back or go into the library module and in here all the way at the top in line number nine there's this mod storage that is currently commented out so we are going to uncomment that and now we have access to a method that is called store asset

and that except two arguments the first one is the actual path that we want to serve the asset from so let's define that one first because it's a metadata it traditionally for some reason doesn't have a Json file ending it's just a token ID and that's it um so yeah in here we are again going to format and this is going to be simple because it's basically just going to be the token ID and that's it and in here again we use the mint event and the token ID and for the actual asset there's a struct that we are going to import that is coming from the storage module create so let's import that and

now um yeah basically write out the the literal um this struct has two Fields the first one are the headers that we want to associate with the asset that we are going to serve in here we only going to set the content type which we're going to set to a text Json and then also the body of the asset which is the yeah bite Vector that we serialized in a step before so let's start with the headers headers and here we are going to use a vector a header is always a tuple of two strings the name of the header which is content type and then the

actual value which is Text slash Json and of course both of these have to be strings um okay now we have the header and the next step is to just use the body down here and that's it now we generated and stored the metadata of the nft and we also made it available through HTTP and the next step is that we are going to generate and store the actual image and again we are going to pass the mint event and the actual attributes to this

method oh that's wrong mint event and attributes and in here as I hinted and as the name also suggests we are going to generate the actual SVG and for this we are going to make use of a create called SVG to create the SVG and then we're going to serialize that SVG into a bite Vector again so let's start with the background we're going to use a rectangle note um I have to import this first

from the SVG crate so a new rectangle node then we're going to set the width of that node to a 100% and we also going to set the height of this 100% and we're going to fill it with the attribute that we generated for the background so attributes and then background color and again we have to clone this so that's all we need for the background and now we're going to create a circle node as well and again we are going to import this node from the SVG

crate we're going to create a new one we're going to set the center of the circle on the X AIS to 50 and the same thing for the y- AIS and then we're also going to set the radius of this to 48 and now of course we also have to fill this with the color and in this case this is of course not the background color but the circle color and now we have our background on top of that we have the circle now we can create the actual SVG document and we are going to use the document exposed

by SVG and we're going to set I have to import this first we're going to set the um view box of this to 0 0 100 and 100 so this is basically a 100 * 100 pixel or Dimension SVG and now we're going to add the background to this the background node and then we are going to add the circle node and for storing the actual um asset we are going to just

copy and paste the store asset function from generate and store metadata and paste it up here and the only thing we have to do is that we have to change the path so this is not uh just a token ID but it's token it. SVG and of course before that we have to serialize this into a body so uh document and then we do two string and then into bytes that should be sufficient um and the content type is of course not a text or adjacent anymore it's now an image and in this case a SVG um

yeah now you generated your metadata you generated your image uh both um using a random number render random number generator uh that in the first place generated the the attributes for the nftd so that is basically all we wanted to do in our our job now I said a couple of times that canister can expose um data via HTTP and to enable that canesas have to expose a a method basically an entry point to the canister that is called HTTP request and expects um the system expects that this method um takes an argument of type HTTP request and returns a HTTP response so to enable our

canister with this functionality we are going into the lip. RS module then we scroll all the way down and then we uncommon this this method that you find here and we also have to import um yeah some of the missing types and the missing get assets function from the storage trade which is basically retrieving the assets that we just previously stored so the metadata and the actual SVG and that's basically it um with regards to the to the back end with regards to building this co-process at canister and building this uh ERC 721 contract so the only thing left to do now is that

we have to modify our deploy script which basically deploys all of this locally and lets us see the result of what we just coded so in here so we use Anil for our basically ethereum Network locally this that that comes with Foundry and an RPC um node built in uh we we this is where we started and will we need this caddy server which is basically an https proxy because otherwise the HTTP out calls don't really work so uh you don't really need to know about it but that's just there for that reason so um after Cy start we are going to insert the script that actually deploys the

ethereum smart contract and we can go all the way down to the deploy script and we can copy the last line and go back up and insert it after KY start and here we have to make a couple of changes the first one is that the script is called nft dos. Soul we can keep this entry point the fork URL is the same we also want to broadcast all of the transactions but we can remove this past uh this part after broadcast so this now deploys our nft contract locally and um yeah basically just runs the script that we defined here to also mint a number of nfts so that we can emit events that we can later on um see using the co-processor

canister and another thing we have to do is that we have to modify the topics that we want to listen for and we can do this down here where we deploy our co-processor canister or this chain Fusion backend canister and previously we were listening for um new job events right in the initial use case but now we want to listen to or four transfer events and as I mentioned uh the first element of this topic is always the event signature so a catcher cache of the event name and the input argument types so if we go back to the um erc721 contract um standard we can we can check

this um transfer event here and we see that it consists of uh three attributes again an address an address and a u 256 so all we have to do now is we look for a online tool to create a Kat 256 has and we're going to pass in the name of the event and then the attribute types which is address address and then u in 256 and we close the parenthesis and that's it this is the event signature that we are oops we are going to pass and now we now we listen for transfer events another thing we have to do is we have to add this z x in front

of this um but we don't want to we don't want to listen to transfer events right we want to listen to Mint events so the second element of this topics that you can also or yeah of the of the lock topics that you can also filter for is going to be this um where is it this from address right so when we are specifying a the zero address as the address and that means that we are only seeing transfers from the zero address which are basically mints in most of the cases um so I'm just going to add a bunch of zeros here and copy paste them until

we have the same amount it looks good and now we can get rid of this old code down here so basically everything um after sleep or with everything after line 66 can be removed and now we have our deploy script and hopefully uh I didn't do any mistakes let me go back and scan over this real quick so yeah of course you can get rid of the Imports that are not needed anymore uh to make everything nice and clean so there's one thing yeah this one does not needed anymore you could also

delete this entire folder up here because it contains logic that we don't need anymore and now let's try running the deploy script so initially like I said we spin up this local uh ethereum Network we then deploy our ethereum smart contract the ERC 721 contract then we are going to Mint 10 nfts and once all of those transaction are successful we are then going to deploy the evm RPC canister which is basically this Gateway canister and this is happening here and this boots up then loading a bunch of stuff those are just like locks

right uh if you deploy in main that you you wouldn't see that and last but not least we're going to deploy the chain Fusion back end and then the chain inion back end as you might remember starts to fetch locks from the ERC 721 contract that we deployed locally and it fetches locks or events that are mint events so there should be 10 of them that we should see okay so there's uh Cate result I think I think I just deleted that so let's just

rebuild so while this is deploying I can already uh talk a bit about what's going on next so next we're going to use cast which is also coming with Foundry and that allows us to make calls to the smart contract that we deployed locally so we're going to use cast call then we are specifying what RPC we want to call so uh D- RPC D URL and this equals to 127 01 and then the port that envil runs on is 8545 and then we have to specify the contract address that we want to call so we can get that from the deploy

script again um so it's this one here because the deployment process already starts uh from the beginning the contract address is deterministic so I can just addit here and it doesn't change and then we also have to specify what we want to call on this contract and that is the as I mentioned earlier the token URI method and that takes one argument which is a uint 256 and it returns a string and now we also have to specify the token ID that you want to get the token URI for uh let's see submit

result uh yeah I should delete this and this this one as well of course weird that I didn't get any red squiggly lines but as always the comp Tyler luckily is your friend um so yeah this might take another minute sorry but maybe I quickly summarize what we achieved so again we have this IRC 721 contract deployed locally right we mint 10 nfts on it every mint emits an event then we also have this co-processor canister deployed locally this co-processor canister listens for events on the ERC 721 contract every time it sees a mint event it then

generates or first let's go through the job actually it first um gets random bytes from the system it uses the random bytes to uh see the random number generator then we use the random number generator to generate the attributes for the nft the attributes are the background color and the circle color and then based on the attributes we are generating and storing the metadata we are generating and storing the image and we exposing both what via HTTP and if the demo gods are with me this should run now okay yeah so now the our canister the chain Fusion backend canister found locks to process and for each lock which is basically a mint event it's now running the logic that we defined in this job method here so now I

should be able to call the token URI method on the erc721 contract if we remember we passed in the can URL as a base URI this gets concatenated with the token ID so we receive a basically a URL back from this call let's try this and this is this canister URL that should hopefully now point to the Json that we generated and luckily it works uh so as you can see we have the attributes in here the the background color the circle color in this case blue and red we have a link to the image which is again a canister URL so this is also stored on the canister and we have the name which is depcon

number one because this is the first nft that we minted and if we now I mean for the sake of demonstration let me just copy this follow the actual image URL you can see that this is the token or the nft that we created so the background color is blue as expected uh Circle color is red so everything worked out so one thing I I did not or I didn't have the time to implement is this Dynamic nft claim that I made right I I said that if you store them on on ipfs they are not really uh dynamic in a decentralized way but if you think about the architecture that we built already and we would imagine that on this year SE 721 contract we expose another method that we maybe call roll for the sake of

the demonstration and that method if if the owner for the like you pass on the token ID and you have to be the owner of the token ID to call a method and if you do that that method emits emits maybe a reroll event and then we can deploy our chain Fusion canister in a way that it doesn't only listen for mint events but it also listens for reroll events and then in the job here we when we um kind of like par or uh convert the lock entry into a mint event we could also add like a um a a second case where it's a reroll event and then depending on whether it's a mint event or a reroll event you could have some custom logic in here you could

for example in the simplest case in both cases no matter if it's a mint event or reroll event you just execute the same logic so you get random bytes again you see the random number generator again and you generate the attributes again so basically you give the user a reroll for their mint and this is yeah fully decentralized it's a damic nft because not only the metadata changes but also the asset change uh there's no no centralized infrastructure involved everything is running on two layer ones basically the internet computer and ethereum and yeah I know um nfts might not be as cool as they were a couple of years ago but um I think with this there are a number of yeah very nice use cases

that that open up and because there are only 5 minutes left let me quickly go back to the final slide here so if you have questions uh I'm I'm around uh all day so if if there's anything that wasn't clear notice was a lot to take in and I was pretty and probably no one was able to follow along but uh if you have any questions you can ask me and if you don't want to ask me you can join the community Discord so we have a Discord server with our developer Community you can also join our developer Forum where you can ask lengthy questions and I'm pretty sure there are people either with inside Affinity or outside Affinity that are more than happy to to answer your questions we also have a pretty big developer grants program so we are uh

allocating $200 million or Swiss Franks for developers that are building cool things in ecosystem I'm part of the grants committee so if you have questions about that feel free to to ask me then if you're still wondering what is the internet computer there's a nice video series that we did together with en Cod club that you can find in this link and then we also have a Wiki page that kind of like shows the similarities and differences um between the internet computer and ethereum uh from the perspective of an ethereum developer and I think I have time for I have three minutes minutes roughly so if anyone has a question that I can answer quickly I'm more than happy to take it if

not I'll let everything sync in for you did anyone follow along out of curiosity or try to follow along yeah and it was probably too quick right okay awesome can you show the QR code of the Finish thing again yeah sure sorry uh that's here there's also I mean this is basically the strip down version that I try to fit into 45 minutes of live coding so if you go to the chain Fusion St a repository and you scroll down there's a more elaborate implementation

of this all the way at the end um that's the same thing but uh it does a bit a couple of things differently and it's like more realistic for a production environment while this might lack I mean yeah probably you want to have more than two attributes um yeah are there solutions to the developer experience because like it took one minute to like run the code again which is not good develop experience I guess yeah is it faster or like is there a solution for that sorry okay um yeah so I was asking if there's a solution for the developer experience because it took about about 1 minute or something okay um because it

took about a minute or something to run the code and um this is quite a lot so are there solutions to this problem um I mean like compiling the the rust code is inevit inevitable uh but because I compiled it the first time or because this deploy script uh oh yeah because I compiled it the first time it took longer like usually I think there's some some caching going on and not not everything has to be Rec compil so in in a if I would run this again it wouldn't take like uh that long hopefully um but yeah I think you always have to compile the RAS code into this into this swm wasm module um so yeah that's probably something that can be sped up or speed

up sorry okay then thank you everyone for attending I appreciate your time and like I said if you have any questions more than happy to answer them um yeah bye [Applause]