Day 08: Advanced Solidity, completing FundMe & setting up a local environment for development.
#100DaysOfCode #MyLearnings
To begin with, I just realized that I've completed 6.30 hours of the 32-hour long course, which is appreciable as am learning & managing the office work alongside, not to mention the workload has increased since the first day of my code challenge. Though it feels like an achievement, it actually is the byproduct of consistency, you really gotta believe in the process in the process & the result is a byproduct eventually.
Though I am managing the consistency somehow, am not disciplined enough & not happy with the efficiency too, gotta work on both & that's gonna be really challenging...
Intro
Talking about the learnings, I covered some advanced Solidity concepts, completed the FundMe project & learned some optimizations to avoid extra spending on gas. As mentioned earlier, blockchain is too expensive & hence optimizations become essential even at the micro level rather than just getting things done. It's interesting & challenging at the same time but more than that it will help me become a better developer in every aspect.
Learnings
Basic Solidity Constructor:
The constructor like any other programming language is used for initializations & initial conditionals & becomes the basis for creating the instance of a class or a contract. The default constructor is always a constructor with no params, & need not be defined…it’d by default.
In our case of FundMe, we want to set the contract publisher/owner to be the only withdrawer of the funds & that is something we could define in the constructor itself instead of adding extra functionality & spending gas.
constructor(){
owner = msg.sender;
}
Basic Solidity Modifiers:
We can create a custom modifier like public, private & so on… which could save our time for writing repetitive code for each method in our case it is to add the owner condition, for now, it’s just for withdrawal but there’s scope for it,
The underscore after the condition represents the body of the particular function we using the modifier on
modifier isOwner{
require(owner == msg.sender, "You don't have withdraw access of funds.");
_;
}
Using modifier for functions:
function withdraw()public isOwner {
for(uint256 i = 0; i < funders.length; i++){
addressToAmountFunded[funders[i]] = 0;
}
}
Advanced Solidity Concepts:
constant keyword
Using constant keywords is gas efficient i.e. consumes lesser gas, & can be used to define one-time initialized variables which won’t get updated further in the code.
uint256 public constant MIN_USD = 50 * 1e18;
Immutable keyword
Using immutable keywords is gas efficient i.e. consumes lesser gas, & can be used for variables that are initialized once in code be it in a constructor or function but don’t need any mutations.
address public immutable i_owner; constructor(){ i_owner = msg.sender; }
Both the above keywords don’t get stored in the storage, instead get stored in the contracts as a bytecode hence consuming less gas.
Replacing require() with if(){revert ErrCode()):
The revert strings we parse in require statements consume more gas as strings are expensive in storage, so instead the new updates provide us with an option to set up an error_code & revert it on not meeting certain conditions in an if conditional.
require(i_owner == msg.sender, "You don't have withdraw access of funds.");
Contract FundMe{
modifier isOwner{
if(i_owner != msg.sender)revert NotOwner();
_;
}
}
//outside the scope of contract
error NotOwner();
Receive & Fallback:
Both the methods are implicit special functions used for handling no method calls while sending ETH which can easily happen in Blockchains. It comes under the low-level interactions in Remix, in which an individual can send ETH without calling the function fund(), in that case, we would get the funds but won’t get any records that we want or we could say that the systematic implementation won’t be followed
This could also happen while sending ETH to this contract directly from Metamash without providing any function call.
- In these cases receive() & fallback() functions come into the picture, if we define both the functions in the contract & write the systematic implementation that we want i.e. fund() in our case these problems can be managed.
Each method comes with a method code/address & that address can be passed into the call data field of Remix to call that method, let’s say the user directly calls the call data field, then the receive() function gets called instead of handling our implementation & if receive() isn’t defined it goes looking for the fallback() implementation, in our case we’ve defined both so it works without throwing error & spending unnecessary gas or completing the transaction without records.
If we parse a method code/address to the call data field & it accidentally won’t match with the fund() method address, in that case, the fallback() gets called handling the implementation.
receive():
receive() external payable { fund(); }
fallback():
fallback() external payable { fund(); }
Learning Progress
Including all the concepts covered above, the learnings moved ahead with completing the FundMe project with funding & withdrawal options. Further optimizations lead to enabling the owner of the contractor to have access to withdrawing the funds, maintaining the funder's records, & handling the edge case of the funder directly funding without the use of the fund method, with the help of the receiver() & fallback().
Learnings with Remix have reached an end & further development will be done on Hardhat in the local environment, which lead to the installation of VScode, Nodejs, & required extensions. Now that the setup is ready, will be using Etherjs & other relevant tools for development as they come & it will help maintain the records in a GitHub repo.
Outro
The learnings are becoming more exciting day by day, getting more challenging concepts to learn, the only important & crucial thing is to be consistent throughout the process. So far these are some of the learnings that I can share with you all, I've tried to put everything as per my understanding & there's a chance that I might've mistaken somewhere, so, feel free to correct me on anything in the comments.
Wrapping up my Day-08 of #100DaysOfCode, will catch up again tomorrow, till then, it's a farewell.