Aspirations
Hey all, hope you all had a great weekend! I did, covered all backlogs & covered up on the course...hoping to complete it sooner. By the way, I've changed my subdomain to https://thedappcoder.hashnode.dev/ & you can find all past & upcoming blogs on it. The Dapp Coder, as in I've kinda sorta on the way to deciding to move ahead with the revolutionary blockchain tech as a career path, not sure when? how? & where? am gonna get the kick start but at least am clear about what I want to do...for now, & am enjoying the journey.
Also, I am planning to start a YouTube channel, focusing on Tech, the Software world, Blockchain, life & more... not sure where/how to begin, but am getting this gut feeling that it would eventually help me improve & be consistent with the learn in public thing, what are your opinions or suggestions on this? The plan is to somehow cover the blockchain course in the next 25-30 days at max & then continue with youtube remaining #100DaysOfCode over YouTube & Open Source Journey in Blockchain. Well, let's see what happens...
I could use my old channel, updated it already, so let me know of any suggestions...
https://www.youtube.com/channel/UCQotgbk9OoZXJXSAEV2Z5yA
Intro
Well, #day7 was quite satisfactory as I almost covered the first mini-project FundMe, learned quite a lot & enjoyed learning too. The best thing about project-based learning is that you cover all levels of concepts at each stage of learning, I've been writing smart contracts & interacting with the Metamask test-net wallet for implementation...from the day I started writing code in Solidity. And today I was working on adding the withdraw funds functionality of FundMe & learned the very beginner-friendly concept of loops, again! This mixture of easy, medium & hard concepts is something that helps me be consistent. Imagine learning only hard concepts...it's frustrating, or earning easy concepts only, it's boring! Having the combo of all of these makes sense & keeps stable throughout the process, that's the reason I like project-based learning.
FundMe Project Overview
The project contains just two functionalities, one is to accept funds & the other is to withdraw the funds. There is a minimum fund amount required if an individual is funding which is 50$, as the user will be paying in terms of ETH, the important part is the currency conversion management from Crypto to FIAT & vice versa, for which we've written two sub functionalities with the help of chain-link's data feed source.
Also, we do store the funder's public address & the amount paid alongside to have a record which is kind of important to appreciate, for which mappings & arrays are used. WIthdraw functionality withdraws all the amount to the withdrawer's account & out of transfer, send & call we've used the preferred way i.e. the call method for withdrawal.
Concepts & Learnings
Interfaces and price feeds
We will be using chain link data feeds to get pricing information
We will be using chain-link price feed to get the ETH-USD prices for which we will need to use the Aggregator contract to listen to price values.
To use the Aggregator of chain-link to get the prices
what we will need is the address & the ABI
the address for Sepolia is given in chain-docs as 0x694AA1769357215DE4FAC081bf1f309aDC325306
& for ABI we could just add the import statement directly from the chainlink & use the instance. It imports the chainlink directly from the npm/GitHub
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
Eth to USD conversions :
Getting the current ETH price in USD…i.e. 1ETH = xx USD….both in wei
The Aggregator possesses two functions that are of use, one being the latestRoundData() providing the latest USD price & the other being the decimals() giving the number of decimals on the price.
We use both ETH & USD prices in Wei for convenience, & to compare both values they both need to be of the same unit sharing the same decimals, i.e. 18 decimals, but the USD price comes with 8 decimals so we converted it to 18 & returned the value.
There are no decimal numbers in Solidity, so we will get the price with 8 zeroes in the end…
If 1 ETH = 300 $ we will get a value of 30000000000 but our ETH has 18 zeroes so we add 10 more zeroes to the price to get a fair value.
function getPrice() view public returns (uint256){
// To use the Aggregtor of chain-link to get the prices
// what we will need is the address & the ABI
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);
// (uint80 roundID, int answer, uint startedAt, uint timeStamp, uint80 answeredInRound)=priceFeed.latestRoundData();
(,int price,,,) = priceFeed.latestRoundData(); // as the only thing we need is price i.e. answer param4
uint8 decimals = priceFeed.decimals();
uint256 deci = 18 - uint256(decimals);
return uint256(price) * (10 ** deci);
}
function convertEthInDollors(uint256 ethAmount) public view returns(uint256){
uint256 eathPrice = getPrice();
// multiplying 18 zeroes on both the numbers will make the number too big, so we will
// limit it to 18 zeroes by dividing by 1e18
return (ethAmount * eathPrice)/1e18;
}
- Condition updated to funded ETH minimum be 50$ convertEthInDollors() converts ETH to equivalent dollars & then to Wei & minUsd is already from dollars to wei so it's a fair conversion & comparison.
uint256 public minUsd = 50 * 1e18;
function fund() public payable {
require(convertEthInDollors(msg.value )>= minUsd, "Please add at least 1 Eth as funds.");
}
LIBRARY IN SOLIDITY:
Libraries can’t have state variables & also they can’t send Ether. They are developed to reduce the repetitive task & we can add custom functionalities like converting ETH to dollars directly to uint data type, so whenever we use a variable of type uint256 we could use that particular functionality on it.
It’s kind of similar to the concept of Extension that we use in Flutter.
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
library PriceConverter{
function convertEthInDollors(uint256 ethAmount) internal view returns(uint256){
uint256 eathPrice = getPrice();
return (ethAmount * eathPrice)/1e18;
}
contract FundMe{
using PriceConverter for uint256;
msg.value.convertEthInDollors();
SafeMath Library, Overflow Checking, unchecked Keyword:
SafeMath library is used to round off the values to the initial values of that particular data type when its max limit is reached. Like in uint8 the max value it could store is 255 & if we increase it by 1, safemath is used to roundoff it to zero instead of throwing off an error.
In newer versions of Solidity default use of SafeMath is deprecated & in some cases, if we need SafeMath, we just need to wrap the code in the unchecked{} block.
SafeMath is gas efficient in some instances where we know that the values won’t overflow in any case.
Fund Transfers:
There are three ways by which we could send money to a specific withdrawer which is the process we are doing in here,
- Transfer
Completes the transaction & throws an error on failure
- Send
Completes the transaction & returns a boolean in case of failure, which then can be added in "require" statements to avoid gas consumption.
- Call (Mostly preferred way)
Completes the transaction & returns a boolean in case of failure & bytes of data returned from the function called in the .call(_functionCall), which then can be added in "require" statements to avoid gas consumption.
// Transfer
payable (msg.sender).transfer(address(this).balance);
// send
bool hasSent = payable (msg.sender).send(address(this).balance);
require(hasSent, "Transaction Failed");
// call
(bool sentSuccess,bytes memory dataReturned ) = payable (msg.sender).call{value: address(this).balance}("");
require(sentSuccess, "Transaction Failed");
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-07 of #100DaysOfCode, will catch up again tomorrow, till then, it's a farewell.