View Methods vs. Transactional Methods
![ThePrimeagen](https://static.frontendmasters.com/assets/teachers/theprimeagen/thumb.webp)
![A Tour of Web 3: Ethereum & Smart Contracts with Solidity](https://static.frontendmasters.com/assets/courses/2022-02-10-web3-smart-contracts/thumb.webp)
Check out a free preview of the full A Tour of Web 3: Ethereum & Smart Contracts with Solidity course
The "View Methods vs. Transactional Methods" 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 modifies the contract so there are separate methods for viewing the count and mutating the count. This best-practice allows method calls to occur without gas fees or verification across the blockchain. Working with larger numbers than JavaScript can support is also covered in this segment.
Transcript from the "View Methods vs. Transactional Methods" Lesson
[00:00:00]
>> And so, let's go on in this thing, because there's our all that information, we went over there, sorry, no data. So the reason why there's no data is, cuz storage is extremely expensive, right? We've altered state, it takes time for transactions to process, which means we're gonna need to re-execute our deploy script.
[00:00:18]
And change some things about our contract. So let's go back to our contract, let's go back to counter, let me just get rid of all these things. And let's change this into two functions, one we're gonna have count. So I'm gonna remove the returns statement, next we're gonna have a public function that is a view this time not pier.
[00:00:43]
And returns the uint of counter, and this simply just returns counter. This is a function in which reads state, this is a function in which writes state. Often that is how you wanna make these two distinctions, when writing contracts. Is you want something that does the mutation, and something that does the reading, reason being is a readings for freezy.
[00:01:09]
That's awesome, but b, you can't really get data out of a write function. You have to wait for the transaction to complete, you have to then go back and read some data about the transaction. It's not as simple as it makes it, whereas this is very, very simple and it works everywhere.
[00:01:26]
It's fantastic.
>> Do those names of functions have to be different?
>> They do have to be different great call, I probably should have done get( counter) that makes a lot more sense, right? I would have had an error, I would have blamed it on everybody for the learning purposes.
[00:01:41]
But kinda missed that opportunity to blame the guy, so we'll just go with this all right. So now that we have this getCounter, return counter, awesome, that means we have to go back to our deploy script, right? We're gonna have to go back, and we're gonna have to change some things.
[00:01:55]
So let's do that now, let's go to our deploy counter and we deploy our script. And then currently we just simply execute it, now I could take the time to show you this, but I'm not going to do it. If we were to simply point to our script now, and try to call getCounter versus count.
[00:02:14]
Obviously, getCounter does not currently exist on our diploids counter, so we have to deploy a new counter script. How you identify a counter is, by its address and its interface, you don't identify it by anything else, right? There's no source code that you're referencing, though you can get the source code.
[00:02:32]
You are referencing simply an address and an interface. So, let's go here, our deploy script is pretty much great, it's this part that's not as great. So let's go here, and let's delete this and let's do a quick count right here. And then we can go await counter, getCounter there we go.
[00:02:53]
So now we're gonna count it once, and then we're gonna get the counter afterwards. Of course don't forget the awaits, if you forget the awaits nothing works. So don't make that mistake. It happens to everybody a few times, everyone loses their promises from now on that, yeah, now that is just part of life.
[00:03:11]
So we're gonna redeploy our counter, and it's gonna cause a new counter to be written to the network that has our new methods. So as it was asked earlier, how do you upgrade your contract? Well, we're doing an upgrade right now, which totally sucks is the current answer.
[00:03:28]
So we're going to hit Enter, and hopefully long as I've done everything correctly, we will see out the answer. So now we did see out the answer, we saw the value of 1. But, it's maybe a little bit different than what you thought. If we look on here, we will see right away that we deployed the counter, it has a new address.
[00:03:46]
We went down here we made a second transition, and we counted count, and then below that we made an eth call. Remember these are reading operations. We called to the counter location, and we called function getCounter from our address, it didn't cost us anything. And we got that information back out, but more so, let's see why does it keep that don't worry about that part.
[00:04:13]
Actually, I already went over this, I forgot to do this quick update right here, sorry, I deviated from my script. So you can only get data out of view and pure functions, as we just showed you. Here's the reasons why doesn't cost any money, it's fantastic. I forgot to explain this part, a view function is one that reads contracts state just doesn't alter it.
[00:04:33]
A pure function does not read or write to contract state, very good to keep in mind, it just specifies what is the state changing. I'll also tell you about some scopes really quickly, public means anyone can call it, private means only you can call it. Internally means only you and your subclasses can call it, externally means only people from the outside can call it, you cannot call it.
[00:04:54]
So it's like public, but different, right? It's a unique public, it's a private public, right? It's also only the public on the outside can call it, these are meant for functions that you only want external people to call. That mutate or change state, that you do not want to ever call within your contract.
[00:05:12]
Do they actually add a lot of value? There is one place that it's used that's very, very nice. But nonetheless, there's the four scopes, you'll probably end up using public, and private, and internal. External, you'll pretty much never use unless you're inheriting from a contractor. So there we go, we rewrote our contract to separate it out.
[00:05:30]
We did the getCOUNT function, it was fantastic. But why, was it a BigNumber? Notice that when we look at our output, it says the word BigNumber value 1 that's a little bit different. Maybe you weren't expecting the word BigNumber, the big out of this. Why are we getting an object, and how could I just didn't get a number, right?
[00:05:50]
Well, let's ask the question, what's the size of an int?
>> 236
>> Great answer, but it's lacking something, where was that int? Well, if it's in JavaScript, a number is technically 2 to the 53 minus 1, or commonly referred to as 9 quadrillion, 7 trillion,199 billion. 256 or 254 million, 740,991, classic number, we all know that by heart, right?
[00:06:18]
Rust you obviously can specify its width i32, or it has u size, which just simply is the size of your system architecture. Cpp kinda has the same thing except for that long, cuz long was it long enough? And it's a little bit more confusing, or you can use these very conveniently named types, right?
[00:06:37]
But everything's trying to convey to you some sort of size, in Solidity, remember, numbers are 256 bits, you were correct. But JavaScript can't do that, right? As you can see 256 bits significantly larger, right? So BigNumber was created by ethers. So it can display these significantly larger numbers that just would not work with JavaScript.
[00:06:58]
So let's do a quick experiment, let's change our number from something that's too big, to something that should be able to fit within JavaScript. So I'm just gonna go back here, you don't have to type this if you don't want to. I'm gonna go to my contract and replace uint with uint32, there we go.
[00:07:12]
And now went from a BigNumber to a smaller number that I have specifically said, hey, you can only be 32 bits long. I'm gonna go back to our deployment script, and just simply relaunch it. And it compiles ye, we've done everything correct, and look at what the value is that comes back out.
[00:07:31]
It's just simply one, so what happened there? Well, it's not a theory of being smart either js is gonna make sure that the type you're using. And the interface you're using is actually gonna produce out the values you would expect in JavaScript, which is very, very convenient. So just kind of a note, if you are using this library and you're returning numbers that don't have to be bounded say by 4 billion.
[00:07:55]
You need more, then you're gonna have to return out a type that may be a bit wonky to work with inside JavaScript. Else you can return out things specifically, you can cast it. If I went back to this and I didn't wanna do that, I could actually come here and do that exact same thing, and then just go uint 32.
[00:08:11]
And just cast it, like you would normally cast it in any other C style language. So now therefore we have that, but you do run the danger, of course, of an overflow. So there's a little bit of a danger there. If you don't know what an overflow is, if you count to 4.2 billion and then you add one on a unsigned 32 bit number.
[00:08:28]
You go above 32 bits, it rolls back all the way over to zero, right? It can get screwed up, because that's just what happens. If you don't know anything about bits, when I go over that section in significant detail, it will make a lot more sense why that happens.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops