Skip to content

Commit

Permalink
Merge pull request #251 from Cyfrin/dev
Browse files Browse the repository at this point in the history
dev --> main
  • Loading branch information
solhosty authored Nov 15, 2024
2 parents fe1f157 + 9b0bfa6 commit 528bf4d
Show file tree
Hide file tree
Showing 82 changed files with 1,380 additions and 1,531 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ If you have any questions or just want to join the discussion, you can do it at
---
[Discord](https://discord.gg/cyfrin)
---
[GitHub](https://github.com/Cyfrin/path-solidity-developer-2023/discussions)
[GitHub](https://github.com/Cyfrin/foundry-full-course-cu/discussions)
---

See you in the next lesson!
See you in the next lesson!
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ _Follow along the course with this video._

Welcome back! I hope you're ready to move into some more advanced concepts in Web3. In this section we're going to be diving into `ERC20s`, and how to develop, deploy and test them.

You can find the code associated with section in the [**GitHub repo**](https://github.com/Cyfrin/foundry-full-course-f23) associated with this course, and in the [**section repo specifically**](https://github.com/Cyfrin/foundry-erc20-f23).
You can find the code associated with section in the [**GitHub repo**](https://github.com/Cyfrin/foundry-full-course-cu) associated with this course, and in the [**section repo specifically**](https://github.com/Cyfrin/foundry-erc20-cu).

Before we rush into creating our own `ERC20 Token`, let's take a moment to learn _what_ an `ERC20` is, what `EIPs` are and where all these acronyms mean.

Expand All @@ -20,11 +20,24 @@ The Web3 and blockchain ecosystem is fundamentally democratic and open source. A

If `EIPs` get enough traction to warrant genuine consideration they will often generate a `Request for Comments`, in Ethereum these are known as `Ethereum Request for Comments` (`ERCs`).

> **NOTE** > `EIPs` and `ERCs` are numbered chronologically! `ERC20` is the 20th request for comments that was created.
> **NOTE**
> `EIPs` and `ERCs` are numbered chronologically! `ERC20` is the 20th request for comments that was created.
New `Improvement Proposals` and `Requests for Comments` are tracked on websites such as [**eips.ethereum.org**](https://eips.ethereum.org/), where you can watch these proposals go through the process real time and be adopted or rejected by the community.

::image{src='/foundry-erc20s/1-erc20-basics/erc20-basics1.png' style='width: 100%; height: auto;'}
::image{src='/foundry-erc20s/1-erc20-basics/erc20-basics1.PNG' style='width: 100%; height: auto;'}

### EIP status terms

- **Idea** - An idea that is pre-draft. This is not tracked within the EIP Repository.
- **Draft** - The first formally tracked stage of an EIP in development. An EIP is merged by an EIP Editor into the EIP repository when properly formatted.
- **Review** - An EIP Author marks an EIP as ready for and requesting Peer Review.
- **Last Call** - This is the final review window for an EIP before moving to FINAL. An EIP editor will assign Last Call status and set a review end date (`last-call-deadline`), typically 14 days later. If this period results in necessary normative changes it will revert the EIP to Review.
- **Final** - This EIP represents the final standard. A Final EIP exists in a state of finality and should only be updated to correct errata and add non-normative clarifications.
- **Stagnant** - Any EIP in Draft or Review if inactive for a period of 6 months or greater is moved to Stagnant. An EIP may be resurrected from this state by Authors or EIP Editors through moving it back to Draft.
- **Withdrawn** - The EIP Author(s) have withdrawn the proposed EIP. This state has finality and can no longer be resurrected using this EIP number. If the idea is pursued at a later date it is considered a new proposal.
- **Living** - A special status for EIPs that are designed to be continually updated and not reach a state of finality. This includes most notably EIP-1.


### ERC20

Expand All @@ -34,7 +47,7 @@ These tokens essentially exists as records of value within smart contracts on ch

**_Why make an ERC20?_**

There are a few common reasons that someone may choose to launch an `ERC20 token`, but there's very little limit to the possibilities of their application in a digital space. A few common usecases include:
There are a few common reasons that someone may choose to launch an `ERC20 token`, but there's very little limit to the possibilities of their application in a digital space. A few common use cases include:

- Governance Tokens
- Securing an underlying network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ _Follow along the course with this video._

### ERC20 Manual Creation

Welcome Back! Having covered the basics, let's look at how we can manually create our own ERC20 token. This is going to be one of our fastest lessons yet!
Welcome back! Having covered the basics, let's look at how we can manually create our own ERC20 token. This is going to be one of our fastest lessons yet!

### Setting Up Your Environment

Open a terminal in Visual Studio Code and run the following:

```sh
mkdir foundry-erc20-f23
cd foundry-erc20-f23
mkdir foundry-erc20
cd foundry-erc20
code .
```

Expand All @@ -38,18 +38,18 @@ I'm going to show you 2 different ways to create our own token, first the hard w

You can begin by creating a new token token our `src` directory named `ManualToken.sol`. We can start this contract the same way we've been practicing this whole time (you'll get really familiar with this bit).

```js
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
contract ManualToken {...}
contract ManualToken {}
```

Now, as we covered in the last lesson, all we need to do to make our token compatible is follow the [**ERC20 Token Standard**](https://eips.ethereum.org/EIPS/eip-20). Essentially this means we need to include the required functions/methods for our deployment to follow this standard. Let's add thing functionality then!

Let's start with name, decimals and totalSupply

```js
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
Expand All @@ -59,7 +59,7 @@ contract ManualToken {
return "Manual Token";
}
function totalSupply() public pure returns (uint256){
function totalSupply() public pure returns (uint256) {
return 100 ether; // 100000000000000000000
}
Expand All @@ -72,9 +72,9 @@ contract ManualToken {
> **NOTE**
> Despite being an optional method, we're including `decimals` here as a point of clarification since we're declaring our total supply as 100 ether. 100 ether = 100 + 18 decimals places.
The next functions required by the ERC20 standard are balanceOf and transfer, so let's apply those now.
The next functions required by the ERC20 standard are `balanceOf` and `transfer`, so let's apply those now.

```js
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
Expand All @@ -100,13 +100,13 @@ contract ManualToken {

Hmm, what is this function meant to return exactly? We're probably going to need a mapping to track the balances of each address...

```js
```solidity
mapping(address => uint256) private s_balances;
```

So now our balanceOf function can return this mapped value based on the address parameter being passed.
So now our `balanceOf` function can return this mapped value based on the address parameter being passed.

```js
```solidity
function balanceOf(address _owner) public pure returns (uint256) {
return balances[_owner];
}
Expand All @@ -119,13 +119,13 @@ An interesting thing that comes to light from this function is - someone's balan
Our next required function is transfer:

```js
```solidity
function transfer(address _to, uint256 _amount) public {
uint256 previousBalance = balanceOf(msg.sender) + balanceOf(_to);
s_balance[msg.sender] -= _amount;
s_balance[_to] += _amount;
require(balanceOf(msg.sender) + balanceOf(_to) == previousBalances);
require(s_balance(msg.sender) + s_balance(_to) == previousBalance);
}
```
Expand All @@ -136,6 +136,6 @@ So, a basic transfer function could look something like the above, a simple adju

We could absolutely continue going through each of the required functions outlined in the [**ERC20 Token Standard**](https://eips.ethereum.org/EIPS/eip-20) and eventually come out the other side with a compatible contract, but there's an easier way.

In the next lesson we'll investigate an even easier method to spin up a standard ERC20 protocol, with the help of OpenZepplin.
In the next lesson, we'll investigate an even easier method to spin up a standard ERC20 protocol, with the help of OpenZeppelin.

See you there!
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ Welcome back! As mentioned in the closing of our last lesson, we could absolutel
In this section, I'll guide you on using the OpenZeppelin Library to achieve this.

> **NOTE**
> OpenZeppelin is renowned for its Smart Contract framework, offering a vast repository of audited contracts readily integratable into your codebase.
> OpenZeppelin is renowned for its Smart Contract framework, offering a vast repository of audited contracts readily integrable into your codebase.
Access [OpenZeppelin's documentation](https://docs.openzeppelin.com/contracts/4.x/) via their official website. By navigating to [Products -> Contracts](https://www.openzeppelin.com/contracts), you can discover a vast array of ready-to-use contracts.
Access [OpenZeppelin's documentation](https://docs.openzeppelin.com/contracts/5.x/) via their official website. By navigating to [Products -> Contracts Library](https://www.openzeppelin.com/contracts), you can discover a vast array of ready-to-use contracts.

Additionally, OpenZeppelin offers a contract wizard, streamlining the contract creation process — perfect for tokens, governances, or custom contracts.

::image{src='/foundry-erc20s/3-erc20-open-zeppelin/ERC20-open-zeppelin1.PNG' style='width: 100%; height: auto;'}
::image{src='/foundry-erc20s/3-erc20-open-zeppelin/erc20-open-zeppelin1.PNG' style='width: 100%; height: auto;'}

Let's leverage OpenZeppelin to create a new ERC20 Token. Create a new file within `src` named `OurToken.sol`. Once that's done, let's install the OpenZeppelin library into our contract.

Expand All @@ -35,7 +35,7 @@ remappings = ["@openzeppelin=lib/openzeppelin-contracts"]

We can now import and inherit this contract into `OurToken.sol`!

```js
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
Expand All @@ -53,14 +53,14 @@ By importing the OpenZeppelin implementation of ERC20 this way, we inherit all t
Now, we should recall that when inheriting from a contract with a constructor, our contract must fulfill the requirements of that constructor. We'll need to define details like a name and symbol for OurToken.

```js
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract OurToken is ERC20 {
constructor(uint256 initialSupply) ERC20("OurToken", "OT"){
constructor(uint256 initialSupply) ERC20("OurToken", "OT") {
_mint(msg.sender, initialSupply);
}
}
Expand All @@ -70,7 +70,7 @@ For the purposes of simple examples like this, I like to mint the initialSupply

As always we can perform a sanity check to assure things are working as expected by running `forge build`.

::image{src='/foundry-erc20s/3-erc20-open-zeppelin/ERC20-open-zeppelin2.PNG' style='width: 100%; height: auto;'}
::image{src='/foundry-erc20s/3-erc20-open-zeppelin/erc20-open-zeppelin2.PNG' style='width: 100%; height: auto;'}

Nailed it.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ We expect OurToken to behave the same, regardless of the chain it's deployed on,

To begin, we can import Script and OurToken as well as add the skeleton of our run function:

```js
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import {Script} from "forge-std/Script.sol";
import {OurToken} from "../src/OurToken.sol";
contract DeployOurToken is Script returns (OurToken){
contract DeployOurToken is Script {
function run() external {}
}
```

We're going to keep this really basic, we just want to deploy OurToken. We know that OurToken requires an initial supply as a constructor parameter, so let's declare that and then deploy our contract.

```js
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
Expand All @@ -55,10 +55,10 @@ contract DeployOurToken is Script {

Our deploy script looks great! To make things a little easier on ourselves when using the CLI to run this script, copy the Makefile from the course GitHub repo and add this to our workspace (I've included it below to copy if needed).

<details>
<summary>Makefile</summary>

```
### Makefile

```make
-include .env

.PHONY: all test clean deploy fund help install snapshot format anvil
Expand Down Expand Up @@ -110,15 +110,15 @@ verify:

```

</details>


Now, by running `make anvil` (open a new terminal once your chain has started!) followed by `make deploy`...

::image{src='/foundry-erc20s/4-erc20-deploy-script/erc20-deploy-script1.png' style='width: 100%; height: auto;'}


### Wrap Up

Woo! Deployment to our anvil chain successful, let's go!

In the next lesson we'll test our contracts with the help of some AI tools and recap everything we've gone over so far. See you there!
In the next lesson, we'll test our contracts with the help of some AI tools and recap everything we've gone over so far. See you there!
Loading

0 comments on commit 528bf4d

Please sign in to comment.