
A First Look at Smart Contracts on Avalanche
A guide to creating and deploying an Avalanche blockchain project, covering MetaMask setup, Solidity smart contracts, and React hosting with Netlify
Episode Description
Anthony Campolo demos building a full-stack dApp from scratch using MetaMask, Hardhat, EtherJS, and React, deployed to Avalanche's Fuji testnet.
Episode Summary
Anthony Campolo walks through building a decentralized application from the ground up in a live workshop format, fielding audience questions along the way. He begins by showing how to configure a MetaMask wallet for the Avalanche Fuji testnet, then scaffolds a React project using Vite and installs the necessary dependencies—Hardhat for smart contract development, EtherJS for blockchain interaction, and environment variable management. The core of the demo centers on a simple "Hello World" Solidity smart contract with read and write functions, which he compiles and deploys to the Avalanche testnet using Hardhat's CLI tools. He then connects the deployed contract to a React frontend, demonstrating how to fetch the stored message and update it through a MetaMask-signed transaction, explaining the distinction between free read operations and gas-requiring write operations. The session wraps up with a deployment of the finished app to Netlify, showing how the frontend and smart contract remain decoupled—state changes persist on-chain regardless of where the UI is hosted. A closing discussion touches on Avalanche's low gas costs compared to Ethereum, the roles of infrastructure providers like QuickNode, and how familiar JavaScript tooling lowers the barrier to entry for web developers moving into Web3.
Chapters
00:00:00 - Setting Up MetaMask and Scaffolding the Project
Anthony introduces the workshop and begins by walking through how to add the Avalanche Fuji C-Chain network to a MetaMask wallet, including the RPC URL, chain ID, currency symbol, and block explorer. An audience member asks about where chain IDs originate, prompting a brief discussion about consulting blockchain documentation for network configuration details.
He then moves into scaffolding a new React project using Vite, explaining how it differs from Create React App by using a faster bundler under the hood. After generating the boilerplate and running the dev server, he installs key dependencies—dotenv, Hardhat, EtherJS, and the Hardhat-Ethers integration library—laying out how each tool fits into the development workflow for someone coming from a JavaScript background.
00:05:12 - Writing and Deploying the Solidity Smart Contract
Anthony opens the Solidity smart contract file and walks through each component: the version pragma, the GPL license, a Hardhat console import, and the HelloWorld contract itself with a string variable, a constructor, a read function, and a write function. He explains how the constructor sets an initial message at deployment time, while the two functions allow reading and updating that message on-chain.
He then covers the Hardhat deployment script, showing how it references the contract factory, calls the deploy method with an initial message, and logs the deployed contract address and signer. The Hardhat config file is discussed in terms of feeding in the QuickNode endpoint URL and wallet private key via environment variables. An audience question about whether deploy scripts are reusable across contracts leads to a clarification that each contract needs its own deploy script referencing the correct contract name.
00:15:05 - Compiling, Deploying, and Connecting React to the Contract
With the environment variables set, Anthony compiles the smart contract to generate the ABI using Hardhat's compile command, then deploys it to the Avalanche Fuji testnet by passing the appropriate network flag. He verifies the deployed contract on Snow Trace, the Avalanche block explorer, confirming it's live on-chain.
The focus then shifts to the React frontend, where he builds out a component using React's useState hook and the EtherJS library to fetch the hello message from the deployed contract. He walks through how the app checks for a MetaMask wallet on the window object, creates a provider and contract instance using the contract address and ABI, and calls the read function to display the stored message. The audience sees the "Hello from QuickNode" message rendered in the browser after clicking a button.
00:19:58 - Adding Write Functionality and Deploying to Netlify
Anthony adds the write function to the React app, introducing a signer alongside the provider so that state-changing transactions can be confirmed through MetaMask. He demonstrates updating the contract's message via an input field and button, explaining the key distinction between free reads and gas-requiring writes, and notes that the testnet uses fake AVAX obtained from a faucet rather than real funds.
He then deploys the entire frontend to Netlify by connecting a Git repository, setting the Vite contract address as an environment variable, and triggering a build. The live site connects to the same on-chain contract, proving that the frontend and smart contract are fully decoupled—state changes persist regardless of where the UI is hosted. The session closes with audience questions about Avalanche's low gas fees compared to Ethereum, the respective roles of QuickNode and Avalanche, and how JavaScript-native tooling makes blockchain development accessible to web developers.
Transcript
00:00:04 - Anthony Campolo
All I'm really going to be doing here is demoing a simple little project. So I'm going to share my screen here.
00:00:12 - Anthony Campolo
Right now what we're going to do is create a project totally from scratch. What we're going to use is MetaMask, Hardhat, and EtherJS. So if at any point people want to jump in and ask questions, feel free. I'm just going to kind of walk through this project. So anytime things don't make sense, just stop me and say, "Hey, what are you doing? What's going on here?" But if you've ever worked with a MetaMask wallet before, then this should be fairly straightforward. This is how you will connect to any kind of blockchain and interact with it in terms of your funds. So we're going to be connecting to Avalanche specifically. And when you first create a wallet, you may have to add the network. So you can do that by inputting data here. The network name will be Avalanche Fuji C-Chain. Then you'll have an RPC URL that has to connect to the Avalanche C-Chain specifically. Then it has a chain ID 43113, currency symbol AVAX, and then a block explorer, which is kind of like an Etherscan that lets you connect and get analytics and data from the blockchain.
00:01:34 - Audience questioner
So the chain ID, who makes up the chain ID? How does that number get assigned? Where does it come from?
00:01:43 - Anthony Campolo
So it comes with the Avalanche docs. When I'm trying to figure out how to connect to something, that's where I go. I don't really know who decides on that and whether it's the wallets or the chain itself. It's a fantastic question that I wish I knew.
00:01:56 - Audience questioner
The answer would be like number one or something.
00:01:58 - Anthony Campolo
Right.
00:01:58 - Audience questioner
And then a different chain would be a different number, right?
00:02:00 - Anthony Campolo
Yeah, exactly. Usually if you just go to the docs or if you Google how to connect a MetaMask wallet to Avalanche, you'll be able to find that kind of information.
00:02:14 - Anthony Campolo
Got it, thank you.
00:02:18 - Anthony Campolo
Are people here familiar with Vite at all? I'd be curious. No, I'm not familiar with it. Okay, so are people familiar with Create React App?
00:02:33 - Audience questioner
I am with both.
00:02:34 - Anthony Campolo
Yeah.
00:02:36 - Anthony Campolo
Great. So Create React App uses something called webpack under the hood, which is what does the whole bundling process, what turns your React app into something that can actually go onto the internet. Whereas Vite is a newer, faster, more updated version of webpack. It's just going to generate a boilerplate React app for us that most of you will be pretty familiar with.
00:03:04 - Anthony Campolo
Just going to...
00:03:07 - Audience questioner
It's a bundler, right?
00:03:08 - Anthony Campolo
Yep, exactly. This is just going to kick open a project for us.
00:03:16 - Anthony Campolo
I'll open this up so you all can see what's happening here.
00:03:23 - Anthony Campolo
We'll go yarn dev and I'll be using Yarn. If you use npm, it's the same kind of thing to run our dev commands.
00:03:37 - Anthony Campolo
And then we'll get it open on localhost 3000.
00:03:43 - Anthony Campolo
This is just like your Create React App. We have a React app and this is what we're going to use to connect to our smart contract.
00:03:55 - Anthony Campolo
We see "Hello" there. And that's our little project. Now what we're going to do is actually get our contract set up and there's going to be a couple dependencies we'll need. The first ones are going to be dotenv for environment variables and then Hardhat, which is our development environment that allows us to deploy our smart contract, and we'll see that as we get into it. And Ethers, which is a JavaScript library that allows you to hook into React hooks and then use that to interact with the blockchain. And then there's this Hardhat Ethers library which kind of integrates the two of them together. If you check out all of these tools, there are various other libraries and tools that do similar things. But these ones are fairly popular and standard when you want to first get going, if you're familiar with the JavaScript toolchain. So this is why as someone who learned a lot of React and Node and stuff like that, this will usually make sense to you. Now we're going to have a couple files here.
00:05:12 - Anthony Campolo
The first one will be our Solidity file. Solidity is the programming language that you use to write your smart contract. Your smart contract is a program that lives on the blockchain. We're then going to have this deploy file, and this is the Hardhat file that actually takes this contract and deploys it for you and will allow you to deploy similar contracts to different chains. So we could specify deploy this to the Ethereum chain or to the Avalanche chain, or to the Avalanche testnet chain and you just kind of pass it flags to do that. And then a config file, the Hardhat config file, which is going to be the actual endpoint that you feed it in.
00:06:00 - Anthony Campolo
And paste these in. There we go.
00:06:05 - Anthony Campolo
Then we also have our environment URLs here. You want to add your .env to .gitignore because that will ensure that you don't actually put your keys in. That was the last step. At some point, we're going to actually see each of those files individually. But does anyone have questions on what just happened there? What was the package you installed after Ethers? Yeah, so it's Nomadic Labs Hardhat Ethers. This is a Nomadic Labs package specifically, which is the company behind Hardhat, I believe. Cool.
00:06:55 - Audience questioner
Thanks, man.
00:06:55 - Anthony Campolo
Yeah, no problem.
00:06:58 - Anthony Campolo
Okay, now let's take a look at our smart contract. This is going to be our Solidity smart contract.
00:07:08 - Anthony Campolo
Let me open this up a little bit so you can see the whole thing at once. What's happening here is we are first going to set the version of Solidity. You always want to define this at the top. And actually the very top is a license, it's a GPL. Then this is going to allow us to console log some information from Hardhat when it's actually deployed. Then there's a contract which is going to be a HelloWorld contract. In this contract there's going to be a hello message variable that's just a string and then there's going to be a constructor that allows us to feed in an input message and then set the hello message. So when we deploy this contract, we're going to give it a little message and when it actually gets deployed then it's going to read that message out as the hello message. Then we have two functions here to interact with the contract, one to read and one to write. The hello function is just going to return the hello message and give it back to us.
00:08:27 - Anthony Campolo
So it's just reading whatever that message is that we set when we deployed it. And then the set hello message will allow us to actually change it. We'll pass in a message and then set it to the hello message variable. And then also we'll console log saying "changing hello message from this to this."
00:08:46 - Anthony Campolo
Does that make sense?
00:08:51 - Audience questioner
Yep.
00:08:52 - Anthony Campolo
Cool.
00:08:56 - Anthony Campolo
This is very similar to what you get when you run Hardhat's basic "generate me a project" thing. I changed a couple of the variable names because originally it's like "greeting" and I find it to be a little bit confusing. This makes a little more sense to my brain. But that's basically what this is. And then same thing with the deployment script here. This deployment script is going to take that contract, which is the HelloWorld contract, and then set it to hello, initialize it as HelloWorld Factory, and then you run the deploy method and feed in that message, which then sets this message to the hello message variable. Then you await it and run .deployed() and then I console log two pieces of information. One is the address of the contract that gets deployed and then the signer of the person who deployed that. The signer comes from your wallet private key in the Hardhat config. So in the Hardhat config, we're going to have our QuickNode URL and then our private key.
00:10:17 - Anthony Campolo
All right, just making sure I'm following all this.
00:10:23 - Audience questioner
Okay.
00:10:24 - Anthony Campolo
Okay, now we got all that. There's a couple things I'm going to have to do in terms of key management. But before doing that, we have QuickNode. This is how you get your endpoint. There's a bunch of different ways you can do this, but this is the one I'll be using. This is the company that I work for.
00:10:52 - Anthony Campolo
I already have an endpoint set up. When you get it set up, you will have this HTTP provider. That has a private key on the end that you don't want to share. So this is why you want to make sure you put it in your .env file and then make sure your .env file is in your .gitignore file. That's really important git hygiene there. Then you're also going to grab your wallet key, which you get from account details. You export your private key and then you put both of those into a .env file. So right now, the .env file doesn't have any of that information yet. So I'm going to stop sharing and do that real quick. Any questions while I do that?
00:11:57 - Audience questioner
Which company did you work for again? Was it Avalanche or QuickNode or are they both the same?
00:12:02 - Anthony Campolo
Yeah, so that's a great question. I work for QuickNode. QuickNode is a blockchain infrastructure company, and Avalanche is the blockchain itself that we're connecting to. So this question of what is a blockchain versus a blockchain company versus a company that works for blockchains, it's a very confusing thing actually. But we are a provider to connect to various different blockchains. Avalanche is one, Ethereum is one, Solana is one. There's like 13 or 14 of them that we offer right now. So our goal is just to give developers the ability to connect to whichever blockchain they want to. That's kind of the idea of QuickNode. Right now I'm demoing Avalanche because this is one of our newer integrations and it's a blockchain that we think has a lot of promise. So we've kind of been creating guides for it and videos and then now going out doing talks about it.
00:13:00 - Audience questioner
Right, great, thanks. I noticed at the top of the CoinDesk.com website right now, there's a huge quarter-page banner for Avalanche. So yeah, nice.
00:13:16 - Anthony Campolo
Okay.
00:13:18 - Audience questioner
I have a question.
00:13:20 - Audience questioner
Yeah, go ahead.
00:13:21 - Audience questioner
The deploy script, the deploy JS script you've shown, is it for just deployment and testing for us or is this something that we will have every time we need to deploy a contract? We will have the same thing. Because I noticed something related to testing the call as well, in the same script, not just deploying.
00:13:41 - Anthony Campolo
Yeah. So the deploy script is fairly generic. Whether you're deploying it to a testnet or a mainnet is going to depend on when you run the deploy command itself, you kind of feed it some flags. And then there's also a separate test file you would write to actually test your contract. The way Hardhat does it is it decouples it into the contract itself, the logic around deploying the contract, and the logic around testing the contract. Each of those gets their own files. Does that make sense?
00:14:14 - Audience questioner
Yeah, sure. So we will need a deploy script for each contract we have.
00:14:21 - Anthony Campolo
Right. The deploy script will need to change based on the contract's name, yes. And then you could deploy a bunch of them at once if you're deploying multiple contracts. Usually when I do this project I just deploy a single contract. So that's actually a good question that I should figure out how to do.
00:14:43 - Audience questioner
Okay, cool. Thank you.
00:14:44 - Anthony Campolo
Yeah, no problem. Okay, let me get back to sharing my screen. Cool. Okay, so now let's get back to this.
00:15:05 - Anthony Campolo
Now we have our contract set up and we have our endpoint and private key in there.
00:15:14 - Anthony Campolo
We can run this compile script and then this is going to compile the ABI, the application binary interface, which is then the thing that you actually deploy to the network. So this is where I was saying we feed in the network flag and then specify the Fuji network in particular, because that is the Avalanche testnet. Like how Ethereum has Ropsten or Rinkeby, they have testnets. It's the same with Avalanche, they have the Fuji testnet.
00:15:43 - Anthony Campolo
And then after this we're going to get this contract address, which you can verify here on SnowTrace. This is the equivalent of an Etherscan.
00:16:02 - Anthony Campolo
And there is our contract. All right, so now what we're going to do is use React to actually connect to this contract. First we're going to set the contract address to the contract in our environment variable.
00:16:34 - Anthony Campolo
And that is one last thing I need to do off screen.
00:16:47 - Anthony Campolo
And then I also have this CSS reset that makes my website look just a little bit nicer.
00:16:57 - Anthony Campolo
Okay, let me just walk through this code real quick. We're going to first do a useState. So if you've used React before, it's like your React 101. If you've never used React before, then this might not make a whole ton of sense, but it's going to set your hello state to wherever you pass the set hello value. We then check for the wallet on the window object and we have our fetch hello function here that will first check the account and then set the provider and then you pass it your contract address and the HelloWorld ABI. This was generated automatically by Hardhat for us in this artifacts file. Then you have the contract with the hello function, which is the function that we defined in our Solidity file, which then takes the message output, sets it to the data object, and then the data object you use on set hello value to set our hello value. Then you have a button which on click runs the fetch hello function and then displays the data in our hello object here. So now we got that all set up.
00:18:32 - Anthony Campolo
Let's run our development server again. Then we're going to make sure that our wallet is connected. Then we'll click here.
00:18:52 - Anthony Campolo
So now we have the "Hello from QuickNode" message being displayed. That's giving us just the message that we set in our deploy script right here. If we want to change that though, we need a setter function to go along with the setter in the HelloWorld Solidity contract. We're going to put it under our fetch hello function. The set hello function is similar, but also takes in a signer because you have to confirm it on your wallet. Then it runs the set hello function and passes in whatever the hello value is. We're also going to have an input and a button to run the set hello function.
00:19:58 - Anthony Campolo
Okay, should be all good to go.
00:20:14 - Anthony Campolo
Now it asks us to make sure we're connected and to confirm the transaction.
00:20:21 - Anthony Campolo
And then that will take a few seconds to go through.
00:20:27 - Audience questioner
So is that the difference between a read and write function, why you needed to sign it?
00:20:33 - Anthony Campolo
Yeah, exactly. Basically reads are free and you can always just read data off the blockchain because the data is the same. It's a replicated database across everyone's nodes. Everyone has the same data and is reading the same thing. But to actually set it requires writing to it and that requires gas. Now we are not using real gas right now because it's a testnet, so we're not actually paying AVAX. This is actually a step that I probably should have mentioned I skipped, which is the test faucet. You have to first include your wallet address and actually give yourself some fake money to do this. So now we'll have a little bit more AVAX in a second after that goes through. That's why you might really want to use something like Avalanche instead of Ethereum, because Ethereum gas prices are really high right now and you can do similar things with much less extra money on your transactions. Okay, so that's kind of the whole app. Now the last step is if you want to deploy this.
00:21:51 - Anthony Campolo
This is pretty cool because if you're someone like me who came up in the whole Jamstack world with things like Netlify and Vercel, this is extremely easy to get online because you basically just have to deploy this React app with the contract address. You can set the build commands in netlify.toml and it's going to run yarn build with Vite and then put all the assets in a dist folder. Then Netlify knows to just deploy that bundle. So I'm going to do that real quick. Are people here familiar with Netlify? I'm curious, have you used it before?
00:22:37 - Audience questioner
I have. I love it.
00:22:40 - Anthony Campolo
Great.
00:22:41 - Anthony Campolo
That's pretty sweet. I'm a fan for sure.
00:22:46 - Audience questioner
It's a fast, easy way to get something online.
00:22:51 - Anthony Campolo
Then the only other thing you have to do is create a git repo. If people don't know what Netlify is, it's like a static site host. If you think of GitHub Pages on steroids, that's how it was first described to me by Brian Douglas. Basically you just take a git repo, sync it to Netlify. Netlify will then trigger a build every time you change something on your git repo and then rebuild the site and push the site up for you. So right now I just created a git repo with this project and then
00:23:34 - Anthony Campolo
we're going to import the site here and give it the name "Getting Started with Avalanche."
00:23:46 - Anthony Campolo
Then we have one environment variable we need to set, which is the Vite contract address,
00:23:57 - Anthony Campolo
which was here.
00:24:01 - Anthony Campolo
That is what lets the frontend know to connect to this contract in particular that we just deployed. And then also give yourself a custom domain here.
00:24:17 - Audience questioner
Question about the ABI. Do you have to deploy the JSON yourself as part of the app too, or is that just done for you with Hardhat?
00:24:28 - Anthony Campolo
Once it's deployed, the contract is just out there and you only need the contract address to interact with it. You may want to commit it if you want a record of that, so you can check the changes of that over time. Whether you want to save that or not is kind of up to you, I suppose.
00:24:47 - Audience questioner
But the ABI, that JSON file is like public with the contract? It's available to connect from the blockchain?
00:24:55 - Anthony Campolo
The parts that you do need are these artifact parts and those are bundled in your React app for you. You do need this because this is what is being imported into your app.
00:25:09 - Audience questioner
Yeah, that's it.
00:25:10 - Anthony Campolo
Yeah, so that's the part you need.
00:25:15 - Anthony Campolo
We also have some other information here.
00:25:22 - Anthony Campolo
So let's go back to this.
00:25:24 - Anthony Campolo
So now this is actually online right now.
00:25:30 - Anthony Campolo
Oops, I'm in the wrong browser.
00:25:43 - Anthony Campolo
It's going to ask us to reconnect. This is a new site instead of the original localhost we were on. We're going to reconnect to it. Here we see how it has that message that we had set the second time because it's the same contract. Anytime you change the state, it'll be changed whether you're deploying the frontend or not, because they're kind of decoupled from each other.
00:26:06 - Anthony Campolo
And now we'll do "from Netlify" and it'll ask you to confirm the transaction and then that will set the contract again.
00:26:29 - Anthony Campolo
All right, cool. So that's the whole end-to-end example. Do people have questions about that? I'll share that link in the chat for anyone who wants it along with the git repo too.
00:26:50 - Audience questioner
Just to comment that it's pretty freaking awesome. I mean there's lots of new concepts in there, but these are the concepts you have to learn to do any of this stuff.
00:27:04 - Audience questioner
This is making it pretty easy. Where's this coming from? Is it QuickNode or Avalanche that's really sort of making this as easy as this? Or is it all of these things?
00:27:15 - Anthony Campolo
I think the big pillars here are the blockchain itself, that's obviously Avalanche. Then there's the dev tooling which is Hardhat, open source stuff, Ethers. And then the actual infrastructure coming from a funded company which is QuickNode. So it's a little bit of all of it coming together in the right pieces. There are a lot of other companies that are giving you infrastructure to connect to blockchains. I think there's lots of people doing this, but for me it makes me think of the same things I got from deployment platforms like Netlify and Vercel, which were giving me a leg up with what I could do with the skill set I had. As someone who was coming into this as a bootcamp student, I didn't know a whole lot. But all this stuff is kind of aimed at someone who knows this type of stuff because it fits in the same mold, especially because the JavaScript ecosystem is just so huge.
00:28:15 - Anthony Campolo
So I think it's a little bit of all of that.
00:28:18 - Audience questioner
Right, great.
00:28:19 - Anthony Campolo
Yeah. Cool.
00:28:23 - Anthony Campolo
Does anyone else have any other questions, comments, anything like that? Cool.
00:28:34 - Anthony Campolo
Well, if anyone wants to find me online, I am AJC Web Dev on pretty much anywhere on the internet. If you want to check out QuickNode, go to quicknode.com and then Avalanche, their website is avax.network. They've got a whole bunch of sites all over the place. Yeah, I think that about wraps it up for me. Thank you everyone for being here. This was a lot of fun. Shout out to the Codementor people who put this together. Darren in particular did a ton of work here. I think Mohammed, are you raising your hand?
00:29:23 - Anthony Campolo
You have something you want to say?
00:29:26 - Anthony Campolo
Yeah, absolutely.
00:29:27 - Audience questioner
Yeah, I think you might have said this while I wasn't here, I came a little bit late. Could you mention something about the cost of the gas fees and the cost of hosting the contract on the Avalanche blockchain compared to the other ones?
00:29:47 - Anthony Campolo
Yeah. So it's going to be all over the place for different chains. Right now just the transaction cost and the gas costs for Ethereum can range from dozens of dollars to hundreds of dollars to thousands at very peak times of high congestion, that's where it gets really high. With Avalanche I'm not sure kind of what the...
00:30:15 - Anthony Campolo
Let's see what Avalanche gas prices are right now.
00:30:18 - Anthony Campolo
I know it's a lot less.
00:30:38 - Audience questioner
Okay.
00:30:38 - Anthony Campolo
Yeah, so it's like fractions of a cent still.
00:30:41 - Anthony Campolo
It's a huge difference. There effectively are almost no transaction costs on something like Avalanche and it's similar with some other chains, but when it actually starts picking up that may change. That's also just because there aren't as many people using it, so it could change over time. As of now it seems to be a lot better set up for a lot more transactions that are going to be a lot cheaper. Yeah, it's an interesting thing to check out. All the chains, the different trade-offs between them, it's very complex and multifaceted. It's a huge matrix of decisions that go into it. You can't ever look at just one number and say this is better because this one number is better, because there's so many other things to take into account. But I think that is definitely one that for me, I've learned a lot just working with it. I think the developer tooling around it seems to be really sophisticated. That is usually what I look for in terms of whether I want to bet on an ecosystem.
00:31:50 - Audience questioner
Yeah. Thanks, Anthony.
00:31:53 - Anthony Campolo
All right, cool. Well thank you very much for being here.
00:31:56 - Anthony Campolo
I think that'll about wrap it up.
00:32:03 - Anthony Campolo
Awesome. Cool. Thank you for that.
00:32:05 - Anthony Campolo
Yeah, and hopefully I'll be doing more of these because I really enjoyed doing this for you all. So if you keep an eye on the Codementors, you may see some more events coming up either for me or maybe some of my co-hosts and coworkers as well. So thank you, everyone.
00:32:19 - Anthony Campolo
Have a good one.
00:32:21 - Audience questioner
Thank you.