Check out a free preview of the full A Tour of Web 3: Ethereum & Smart Contracts with Solidity course

The "Gas Reporter" Lesson is part of the full, A Tour of Web 3: Ethereum & Smart Contracts with Solidity course featured in this preview video. Here's what you'd learn in this lesson:

ThePrimeagen demonstrates how to use the hardhat-gas-reporter module to estimate gas fees for a contract. The module is included in the hardhat config file. After the contract is created, a test script is written to call methods in the contract. The gas report is displayed in the console.


Transcript from the "Gas Reporter" Lesson

>> Well, I found a better way to do things, is just write a contract and let's just see how much the gas costs. So I'm gonna do something really quickly. I'm just gonna write a couple functions, we're gonna look at them and we're gonna see how expensive they kind of operate.

On top of that we're gonna use this cool thing called hardhat-gas-reporter. So I'm gonna take this, I'm gonna copy it. Again, score is going northward. At this point, buy the stocks, buy the options, we're going so fast. So we're gonna add a bunch of new libraries to our contract, and there we go, awesome.

And then I'm gonna add this line to my hardhat config. By adding these import statements to the config, what ends up happening is that when we execute MPX hardhat, it grabs the config, it loads it and thus loads in these libraries as well. So let's go back in here, let's go into hardhat, go to the top, paste it in.

Now remember this part you don't have to do I'm just doing it if you want to do it, awesome, you can follow along but I'm gonna move quick enough that we can make time for the other parts. All right, there we go. So now I'm gonna just open up a contract and I'm gonna create TestGas.sol, I'm gonna do the pregma statement.

Thank you Tap9 for completing it for me. And I'm gonna do contract TestGas, I'm gonna do a quick uint a, and I'm gonna create three items on the contract, right? b, c and I'm gonna create a function test 1, and it's gonna be public, I'm simply gonna go a++.

We're just gonna increment something that exists on the chain. We're gonna save, we're gonna read one word and save one word, cuz that's what's happening. A word of course is 256 bits. Word tends to be the phrase people use to describe the size of the architecture. So a word on a therium is that.

So test 2 is gonna be two increments. Test 3 of course will be three increments and then we can do one more, test test 4, I don't know why it didn't just copy and paste this public and we're gonna go c equals a plus b. Do a little bit more reading than writing and then we'll do, let's call that one 4 and then let's do one more where we call, Let's call test 4, and then do b equals c plus 8.

Do like a little extra. Do actual function invocation plus the same thing we did in 4. So we can kinda see what does it cost to say, call a function as we're doing right here. Cuz if we just compare the difference between these two, we can see that.

Here, we can kinda see the growth of gas as we call these. So now along with our hardhat reporter, all we need to do now is just create a test. So how the hardhat reporter works, I'm gonna delete hello world, TestGas.ts paste this in. Test gas, test why not?

We're gonna go in here and I'm gonna just rename this thing to gas why not, do a couple renaming and effectively what I am doing here is I'm gonna deploy your gas contract and now we're just gonna call those functions but I'm gonna call them in the loop.

The reason being is that the first time you write to the network on a non written spot it's more expensive because at that point it doesn't have anything in that position. So it actually has to underneath the hood create a kind of a key value so can look at up later on.

And this will become more obvious in a little bit. But for now, just remember that. I just remember I don't have a remap, there we go. All right, perfect. So I'm gonna go 4, let i = 0, i has to be less than 10, why not? So we're gonna do it 10 times, and then we're gonna just simply do this, gas await gas.test 1, There we go, we have all five of our tests, right?

I think that's what we did. Let's just make sure we have that. So let's see. Yeap, there we go. Test 4-5, there we go. So now I'm gonna test take this, I'm gonna go npx hardhat test. Now we have that little gas reporter. So what that gas report is gonna do is it's actually gonna go through and give us a bunch of information.

So let me make this a little bit smaller. So you'll notice that test 1 on average took 28,000 gas. Meaning that writing to a single variable cost that much. Now for whatever reason, as we wrote more, it did seem to scale at a linear rate but it wasn't as expensive as 28,000, right?

It looks like it cost about 5000 at a time. And so you can kinda use this to start guessing how expensive are these functions gonna be. We can do the same thing here, a couple reads plus a right is obviously more expensive than this, right? But it doesn't seem to be that much more expensive.

A function invocation guessing by this is about 500 gas used. Because test 4 and 5, the only difference was executing an extra round and just doing a function invocation. So for whatever reason it looks like the more you write, it doesn't seem to be as expensive. Now part of that reason is that what aethalium does is it comes in it has the state of your contract, you do a bunch of things to that contract.

When it succeeds, it writes all those state changes back to it because it needs to be able to revert just in case something goes wrong. Which means that the more things you write into obviously the cheaper it is because you're doing a bunch of state change transactions in a single spot, and it doesn't actually write back those changes to the end.

And so that's why you can see that it did not scale as fast as you thought it would. I would expect it to be 28,000 then like 56,000 and then it goes up way faster but it doesn't. And then this one is even more telling in the sense that we actually call a function that costs 30,000 by itself, but calling that function plus doing the same thing only cost slightly more.

Cuz we're reading and writing to the same variables a punch. And so that's kinda how you gotta look at gas, I highly recommend getting this cuz it's gonna give you a lot of information, right? It's gonna say, hey, this is pretty much how much it cost to deploy your contract so we can take that and go, okay, so if I wanna deploy my contract, I need to take this times 4000 times say the cost of gas right now divided by 10 to the 9.

And to deploy this contract it's gonna take us approximately $15 to have this test contract on the main net. And so it's good to be able to go through that and kind of estimate what things are gonna cost. And gas is really confusing. It's hard to find any articles that make any sort of sense about it.

So that is as best as I can do with the exploration that I have done. I bet you there's a better explanation that exists out there, it's just that you try to read anything and it's super just non-straightforward. And so that's how I effectively got the best I could.

Is by just doing more empirical evidence as opposed to, here's theoretically what's happening. All right, so some key takeaways. Everything costs money, be careful. The second one is that a lot of people come from a JavaScript like world or a very functional world where copying is like pretty cool, don't copy, it's expensive.

Everything you do cost money, right? You have to be like so much different mindset in solidity than you would in any other language because everything you do is so expensive. So if you had an array, and let's say we wanted to walk this array, and we wanted to like pull out things we liked, would we pull out those things and actually do a splice and remove it from the array?

No, that'd be super duper expensive cuz then you'd have to adjust all the other elements. You try to do as little as possible, right? You have to become really smart and we're actually gonna to do that here shortly but trying to think of things in the smartest possible way doing the littlest amount of mutation is the best possible kind of route when it comes to this.

And for me that's obviously a hard place if you're coming from more of a loosey-goosey world where everything's fine, right? If you're fine executing a react to reconcile, you're probably fine with a lot of compute cycles happening. Whereas here you just don't get that opportunity.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now