Cover photo

Circolors Solidity Sundays #3

We made it to week 3, congrats to people who are still here quenching that thirst for KNOWLEDGE (I’m Tai Lopez now).

Quick Recap of what we’ve done so far for anyone picking it up here:

Week 1

In our first week we introduced Solidity, some of the basic syntax involved as well as how to create a contract/function. Link here

Week 2

Then in week 2 we built on top of the basic contract we started with as well as introduced some global variables in solidity such as block.number and require blocks to give you some control over how people use the functions you create. Link here

What’s next?

Week 3 will be the last week with the very basic contract we made at the start of Week 1 before moving onto something a bit more useable (will explain more at the end).

But as for this week we’ll be building in some functionality for setting the ‘daysSinceDegened’ function we created last week. More specifically we want to be able to let the user add a day to their ‘daysSinceDegened’ value if they go 24 hours without minting something stupid. As well as this we also want to allow them to reset their counter back to zero when they succumb to minting Bored Kevins Yacht Club.

Our week 3 code
Our week 3 code

First our incremementDaysSinceDegened function (add one to the DaysSinceDegened function we created last week.

function incremementDaysSinceDegened() public { 
}

So in the function assignment you can see it’s set to public meaning this function is viewable by anyone. But after that you can see there are some requirements on who can call this function.

require(daysSinceDegenedSet == true, "Counter not set");
require(daysSinceDegenedChange + 24 hours <= block.timestamp, "Must wait 24 hours to increment days");

Here we first require that daysSinceDegenedSet has been set, you can’t add one to the total if the user has never set the total. Then in the second line things get a little more interesting. We require that daysSinceDegenedChange plus 24 hours is sometime before the current block.timestamp. As you might have noticed, in Solidity you’re able to use time units (number + seconds, minutes, hours, days), this is very useful for functions such as this, as well as things such as setting mint deadlines in NFT contracts or lock times for staking. One thing to note about the time units is that they’re not ultra specific or reliable to the nearest second, but as long as you don’t need ultra precision they are a bit better for user experience to know how many minutes and hours they have left to do something rather than the more precise (but less user friendly) block.number (“make sure you mint your NFT in the next 327 blocks!”).

So now anyone who’s made it past our requirements has set their daysSinceDegened counter at least 24 hours ago.

daysSinceDegenedChange = block.timestamp;
daysSinceDegened++;

Next up we change the daysSinceDegenedChange variable to the current block.timestamp to update the timer we just checked in the last line. This is something that’s easy to miss and create an exploit in your contract where the user would be able to infinitely add one day to their counter if we didn’t make sure to always reset the timer after each function call. Obviously within the context of our contract it wouldn’t be that big a deal but can become easy to abuse when real ETH is involved.

Then finally we add one to the variable. Nice we’ve gone 24 hours without an incident, yay personal growth!

But what about when we fail and need to start our timer back at 0? Let’s look at our second function resetDaysSinceDegened.

function resetDaysSinceDegened() public {
}

We should be becoming comfortable with the simple function set up now function functionName() visibilty {}, there are a few more things that will complicate this a bit later but this is the minimum we need to add when making a function.

require(daysSinceDegenedSet == true, "Counter not set");

This time only one requirement? Talk quietly amongst yourselves about why we don’t need the timer check from the previous function.

Well, as all this function is doing is resetting our counter to 0 it doesn’t matter whether the user has gone 24 hours since their last action as they’ve been very naughty and need their progress wiped back to 0.

daysSinceDegenedChange = block.timestamp;
daysSinceDegened = 0;

Again we reset the daysSinceDegenedChange timer to the current block.timestamp, otherwise the user would potentially be able to instantly call incrementDaysSinceDegened add sneakily add an extra day (Before that function reset the daysSinceDegenedChange variable). Then once we’ve reset the timer, instead of adding one to daysSinceDegened we just set it equal to 0. Now our user is back to square one. Simple!

In Summary

So overall in these first 3 mini lessons we’ve managed to create a contract where a user can set themselves a username and flex how many days they’ve gone without degenning into a terrible NFT (Is a big number or small number the flex? I’m not sure). However the gigabrains might have realised a large problem with our contract?

What happens if we have two users?

Currently our contract can only keep track of one persons details, so for someone to actually use this contract they’d have to deploy their own instance of the contract (lots of gas paid) which seems kind of counter intuitive and unnecessarily ocean boily. This leads us onto the plan for week #4 where we’ll take this contracts base functionality and adapt our contract so it could include as many different users as we require.

So congrats to anyone who’s made it this far, I’m hoping these mini lessons at least make it so people feel a little more comfortable reading through smart contract code before they ape into things, but of course my dream for you is to take this and start writing some contracts of your own. Don’t disappoint me anon!

Also shoutout @smokeytom1 again for another banner for this weeks blog!

As usual any questions direct to my twitter or the Circolors Discord.

See you next week ❤